X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Flvfs%2Ffsfilt_ext3.c;h=e65ce42a9e657da1b3263de9556ce3788d778164;hb=b5bf04fb27d8e3e455aec024d8b908a10434519f;hp=6164a09a8d7d33d443647828e0922d9ad766aa8f;hpb=eef822668e9c4794fc5f06747e03985518fa1d19;p=fs%2Flustre-release.git diff --git a/lustre/lvfs/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c index 6164a09..e65ce42 100644 --- a/lustre/lvfs/fsfilt_ext3.c +++ b/lustre/lvfs/fsfilt_ext3.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -61,6 +60,13 @@ #define FSFILT_DELETE_TRANS_BLOCKS(sb) EXT3_DELETE_TRANS_BLOCKS(sb) #endif +#ifdef EXT3_SINGLEDATA_TRANS_BLOCKS_HAS_SB +/* for kernels 2.6.18 and later */ +#define FSFILT_SINGLEDATA_TRANS_BLOCKS(sb) EXT3_SINGLEDATA_TRANS_BLOCKS(sb) +#else +#define FSFILT_SINGLEDATA_TRANS_BLOCKS(sb) EXT3_SINGLEDATA_TRANS_BLOCKS +#endif + #define fsfilt_ext3_journal_start(inode, nblocks) ext3_journal_start(inode, nblocks) #define fsfilt_ext3_journal_stop(handle) ext3_journal_stop(handle) @@ -91,9 +97,7 @@ static int fsfilt_ext3_set_label(struct super_block *sb, char *label) int err; journal = EXT3_SB(sb)->s_journal; - lock_24kernel(); handle = journal_start(journal, 1); - unlock_24kernel(); if (IS_ERR(handle)) { CERROR("can't start transaction\n"); return(PTR_ERR(handle)); @@ -109,9 +113,7 @@ static int fsfilt_ext3_set_label(struct super_block *sb, char *label) err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); out: - lock_24kernel(); journal_stop(handle); - unlock_24kernel(); return(err); } @@ -153,7 +155,7 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private, int logs) { /* For updates to the last received file */ - int nblocks = EXT3_SINGLEDATA_TRANS_BLOCKS; + int nblocks = FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb); journal_t *journal; void *handle; @@ -169,11 +171,11 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private, /* delete one file + create/update logs for each stripe */ nblocks += FSFILT_DELETE_TRANS_BLOCKS(inode->i_sb); nblocks += (EXT3_INDEX_EXTRA_TRANS_BLOCKS + - EXT3_SINGLEDATA_TRANS_BLOCKS) * logs; + FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb)) * logs; break; case FSFILT_OP_RENAME: /* modify additional directory */ - nblocks += EXT3_SINGLEDATA_TRANS_BLOCKS; + nblocks += FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb); /* no break */ case FSFILT_OP_SYMLINK: /* additional block + block bitmap + GDT for long symlink */ @@ -207,7 +209,7 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private, FSFILT_DATA_TRANS_BLOCKS(inode->i_sb); /* create/update logs for each stripe */ nblocks += (EXT3_INDEX_EXTRA_TRANS_BLOCKS + - EXT3_SINGLEDATA_TRANS_BLOCKS) * logs; + FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb)) * logs; break; case FSFILT_OP_SETATTR: /* Setattr on inode */ @@ -216,7 +218,7 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private, FSFILT_DATA_TRANS_BLOCKS(inode->i_sb); /* quota chown log for each stripe */ nblocks += (EXT3_INDEX_EXTRA_TRANS_BLOCKS + - EXT3_SINGLEDATA_TRANS_BLOCKS) * logs; + FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb)) * logs; break; case FSFILT_OP_CANCEL_UNLINK: /* blocks for log header bitmap update OR @@ -232,7 +234,7 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private, /*create array log for head file*/ nblocks += 3; nblocks += (EXT3_INDEX_EXTRA_TRANS_BLOCKS + - EXT3_SINGLEDATA_TRANS_BLOCKS); + FSFILT_SINGLEDATA_TRANS_BLOCKS(inode->i_sb)); /*update head file array */ nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS + FSFILT_DATA_TRANS_BLOCKS(inode->i_sb); @@ -251,9 +253,7 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private, journal_start: LASSERTF(nblocks > 0, "can't start %d credit transaction\n", nblocks); - lock_24kernel(); handle = fsfilt_ext3_journal_start(inode, nblocks); - unlock_24kernel(); if (!IS_ERR(handle)) LASSERT(current->journal_info == handle); @@ -340,7 +340,7 @@ static int fsfilt_ext3_credits_needed(int objcount, struct fsfilt_objinfo *fso, * quota file that is active. This is at least true for now. */ needed += hweight32(sb_any_quota_enabled(sb)) * - EXT3_SINGLEDATA_TRANS_BLOCKS; + FSFILT_SINGLEDATA_TRANS_BLOCKS(sb); #endif return needed; @@ -390,9 +390,7 @@ static void *fsfilt_ext3_brw_start(int objcount, struct fsfilt_objinfo *fso, } LASSERTF(needed > 0, "can't start %d credit transaction\n", needed); - lock_24kernel(); handle = fsfilt_ext3_journal_start(fso->fso_dentry->d_inode, needed); - unlock_24kernel(); if (IS_ERR(handle)) { CERROR("can't get handle for %d credits: rc = %ld\n", needed, PTR_ERR(handle)); @@ -432,9 +430,7 @@ static int fsfilt_ext3_commit(struct inode *inode, void *h, int force_sync) if (force_sync) handle->h_sync = 1; /* recovery likes this */ - lock_24kernel(); rc = fsfilt_ext3_journal_stop(handle); - unlock_24kernel(); return rc; } @@ -450,7 +446,6 @@ static int fsfilt_ext3_commit_async(struct inode *inode, void *h, LASSERT(current->journal_info == handle); - lock_24kernel(); transaction = handle->h_transaction; journal = transaction->t_journal; tid = transaction->t_tid; @@ -459,18 +454,9 @@ static int fsfilt_ext3_commit_async(struct inode *inode, void *h, rc = fsfilt_ext3_journal_stop(handle); if (rc) { CERROR("error while stopping transaction: %d\n", rc); - unlock_24kernel(); return rc; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - rtid = log_start_commit(journal, transaction); - if (rtid != tid) - CERROR("strange race: %lu != %lu\n", - (unsigned long) tid, (unsigned long) rtid); -#else log_start_commit(journal, tid); -#endif - unlock_24kernel(); *wait_handle = (void *) tid; CDEBUG(D_INODE, "commit async: %lu\n", (unsigned long) tid); @@ -499,8 +485,6 @@ static int fsfilt_ext3_setattr(struct dentry *dentry, void *handle, struct inode *inode = dentry->d_inode; int rc = 0; - lock_kernel(); - /* Avoid marking the inode dirty on the superblock list unnecessarily. * We are already writing the inode to disk as part of this * transaction and want to avoid a lot of extra inode writeout @@ -551,7 +535,6 @@ static int fsfilt_ext3_setattr(struct dentry *dentry, void *handle, } out: - unlock_kernel(); RETURN(rc); } @@ -582,13 +565,11 @@ static int fsfilt_ext3_set_md(struct inode *inode, void *handle, LASSERT(TRYLOCK_INODE_MUTEX(inode) == 0); - lock_24kernel(); rc = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_TRUSTED, name, lmm, lmm_size, 0); - unlock_24kernel(); - if (rc) + if (rc && rc != -EROFS) CERROR("error adding MD data to inode %lu: rc = %d\n", inode->i_ino, rc); return rc; @@ -601,11 +582,9 @@ static int fsfilt_ext3_get_md(struct inode *inode, void *lmm, int lmm_size, int rc; LASSERT(TRYLOCK_INODE_MUTEX(inode) == 0); - lock_24kernel(); rc = ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name, lmm, lmm_size); - unlock_24kernel(); /* This gives us the MD size */ if (lmm == NULL) @@ -709,10 +688,8 @@ static int fsfilt_ext3_add_journal_cb(struct obd_device *obd, __u64 last_rcvd, fcb->cb_data = cb_data; CDEBUG(D_EXT2, "set callback for last_rcvd: "LPD64"\n", last_rcvd); - lock_24kernel(); journal_callback_set(handle, fsfilt_ext3_cb_func, (struct journal_callback *)fcb); - unlock_24kernel(); return 0; } @@ -764,6 +741,25 @@ static int fsfilt_ext3_sync(struct super_block *sb) #define ext3_down_truncate_sem(inode) mutex_lock(&EXT3_I(inode)->truncate_mutex); #endif +#ifndef EXT_ASSERT +#define EXT_ASSERT(cond) BUG_ON(!(cond)) +#endif + +#ifdef EXT3_EXT_HAS_NO_TREE +/* for kernels 2.6.18 and later */ +#define ext3_ext_base inode +#define ext3_ext_base2inode(inode) (inode) +#define EXT_DEPTH(inode) ext_depth(inode) +#define EXT_GENERATION(inode) ext_generation(inode) +#define fsfilt_ext3_ext_walk_space(inode, block, num, cb, cbdata) \ + ext3_ext_walk_space(inode, block, num, cb, cbdata); +#else +#define ext3_ext_base ext3_extents_tree +#define ext3_ext_base2inode(tree) (tree->inode) +#define fsfilt_ext3_ext_walk_space(tree, block, num, cb, cbdata) \ + ext3_ext_walk_space(tree, block, num, cb); +#endif + #include #if EXT3_EXT_MAGIC == 0xf301 #define ee_start e_start @@ -828,43 +824,43 @@ static int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path, unmap_underlying_metadata((sb)->s_bdev, blocknr) #ifndef EXT3_MB_HINT_GROUP_ALLOC -static unsigned long new_blocks(handle_t *handle, struct ext3_extents_tree *tree, +static unsigned long new_blocks(handle_t *handle, struct ext3_ext_base *base, struct ext3_ext_path *path, unsigned long block, - int *count, int *err) + unsigned long *count, int *err) { unsigned long pblock, goal; int aflags = 0; + struct inode *inode = ext3_ext_base2inode(base); - goal = ext3_ext_find_goal(tree->inode, path, block, &aflags); + goal = ext3_ext_find_goal(inode, path, block, &aflags); aflags |= 2; /* block have been already reserved */ - lock_24kernel(); - pblock = ext3_mb_new_blocks(handle, tree->inode, goal, count, aflags, err); - unlock_24kernel(); + pblock = ext3_mb_new_blocks(handle, inode, goal, count, aflags, err); return pblock; } #else -static unsigned long new_blocks(handle_t *handle, struct ext3_extents_tree *tree, +static unsigned long new_blocks(handle_t *handle, struct ext3_ext_base *base, struct ext3_ext_path *path, unsigned long block, - int *count, int *err) + unsigned long *count, int *err) { + struct inode *inode = ext3_ext_base2inode(base); struct ext3_allocation_request ar; unsigned long pblock; int aflags; /* find neighbour allocated blocks */ ar.lleft = block; - *err = ext3_ext_search_left(tree, path, &ar.lleft, &ar.pleft); + *err = ext3_ext_search_left(base, path, &ar.lleft, &ar.pleft); if (*err) return 0; ar.lright = block; - *err = ext3_ext_search_right(tree, path, &ar.lright, &ar.pright); + *err = ext3_ext_search_right(base, path, &ar.lright, &ar.pright); if (*err) return 0; /* allocate new block */ - ar.goal = ext3_ext_find_goal(tree->inode, path, block, &aflags); - ar.inode = tree->inode; + ar.goal = ext3_ext_find_goal(inode, path, block, &aflags); + ar.inode = inode; ar.logical = block; ar.len = *count; ar.flags = EXT3_MB_HINT_DATA; @@ -875,19 +871,29 @@ static unsigned long new_blocks(handle_t *handle, struct ext3_extents_tree *tree } #endif -static int ext3_ext_new_extent_cb(struct ext3_extents_tree *tree, +#ifdef EXT3_EXT_HAS_NO_TREE +static int ext3_ext_new_extent_cb(struct ext3_ext_base *base, + struct ext3_ext_path *path, + struct ext3_ext_cache *cex, + void *cbdata) +{ + struct bpointers *bp = cbdata; +#else +static int ext3_ext_new_extent_cb(struct ext3_ext_base *base, struct ext3_ext_path *path, struct ext3_ext_cache *cex) { - struct inode *inode = tree->inode; - struct bpointers *bp = tree->private; + struct bpointers *bp = base->private; +#endif + struct inode *inode = ext3_ext_base2inode(base); struct ext3_extent nex; unsigned long pblock; unsigned long tgen; - int count, err, i; + int err, i; + unsigned long count; handle_t *handle; - i = EXT_DEPTH(tree); + i = EXT_DEPTH(base); EXT_ASSERT(i == path->p_depth); EXT_ASSERT(path[i].p_hdr); @@ -915,29 +921,25 @@ static int ext3_ext_new_extent_cb(struct ext3_extents_tree *tree, return EXT_CONTINUE; } - tgen = EXT_GENERATION(tree); - count = ext3_ext_calc_credits_for_insert(tree, path); + tgen = EXT_GENERATION(base); + count = ext3_ext_calc_credits_for_insert(base, path); ext3_up_truncate_sem(inode); - lock_24kernel(); handle = fsfilt_ext3_journal_start(inode, count+EXT3_ALLOC_NEEDED+1); - unlock_24kernel(); if (IS_ERR(handle)) { ext3_down_truncate_sem(inode); return PTR_ERR(handle); } ext3_down_truncate_sem(inode); - if (tgen != EXT_GENERATION(tree)) { + if (tgen != EXT_GENERATION(base)) { /* the tree has changed. so path can be invalid at moment */ - lock_24kernel(); fsfilt_ext3_journal_stop(handle); - unlock_24kernel(); return EXT_REPEAT; } count = cex->ec_len; - pblock = new_blocks(handle, tree, path, cex->ec_block, &count, &err); + pblock = new_blocks(handle, base, path, cex->ec_block, &count, &err); if (!pblock) goto out; EXT_ASSERT(count <= cex->ec_len); @@ -946,7 +948,7 @@ static int ext3_ext_new_extent_cb(struct ext3_extents_tree *tree, nex.ee_block = cex->ec_block; nex.ee_start = pblock; nex.ee_len = count; - err = ext3_ext_insert_extent(handle, tree, path, &nex); + err = ext3_ext_insert_extent(handle, base, path, &nex); if (err) { CERROR("can't insert extent: %d\n", err); /* XXX: export ext3_free_blocks() */ @@ -965,9 +967,7 @@ static int ext3_ext_new_extent_cb(struct ext3_extents_tree *tree, BUG_ON(nex.ee_block != cex->ec_block); out: - lock_24kernel(); fsfilt_ext3_journal_stop(handle); - unlock_24kernel(); map: if (err >= 0) { /* map blocks */ @@ -1009,15 +1009,22 @@ int fsfilt_map_nblocks(struct inode *inode, unsigned long block, unsigned long num, unsigned long *blocks, int *created, int create) { +#ifdef EXT3_EXT_HAS_NO_TREE + struct ext3_ext_base *base = inode; +#else struct ext3_extents_tree tree; + struct ext3_ext_base *base = &tree; +#endif struct bpointers bp; int err; CDEBUG(D_OTHER, "blocks %lu-%lu requested for inode %u\n", block, block + num - 1, (unsigned) inode->i_ino); - ext3_init_tree_desc(&tree, inode); +#ifndef EXT3_EXT_HAS_NO_TREE + ext3_init_tree_desc(base, inode); tree.private = &bp; +#endif bp.blocks = blocks; bp.created = created; bp.start = block; @@ -1025,8 +1032,9 @@ int fsfilt_map_nblocks(struct inode *inode, unsigned long block, bp.create = create; ext3_down_truncate_sem(inode); - err = ext3_ext_walk_space(&tree, block, num, ext3_ext_new_extent_cb); - ext3_ext_invalidate_cache(&tree); + err = fsfilt_ext3_ext_walk_space(base, block, num, + ext3_ext_new_extent_cb, &bp); + ext3_ext_invalidate_cache(base); ext3_up_truncate_sem(inode); return err; @@ -1260,10 +1268,8 @@ static int fsfilt_ext3_write_record(struct file *file, void *buf, int bufsize, block_count = (*offs & (blocksize - 1)) + bufsize; block_count = (block_count + blocksize - 1) >> inode->i_blkbits; - lock_24kernel(); handle = fsfilt_ext3_journal_start(inode, block_count * FSFILT_DATA_TRANS_BLOCKS(inode->i_sb) + 2); - unlock_24kernel(); if (IS_ERR(handle)) { CERROR("can't start transaction for %d blocks (%d bytes)\n", block_count * FSFILT_DATA_TRANS_BLOCKS(inode->i_sb) + 2, bufsize); @@ -1275,9 +1281,7 @@ static int fsfilt_ext3_write_record(struct file *file, void *buf, int bufsize, if (!err && force_sync) handle->h_sync = 1; /* recovery likes this */ - lock_24kernel(); fsfilt_ext3_journal_stop(handle); - unlock_24kernel(); return err; } @@ -1768,7 +1772,7 @@ static int commit_chkquot(struct super_block *sb, struct qchk_ctxt *qctxt, if (!oqc) RETURN(-ENOMEM); - now = CURRENT_SECONDS; + now = cfs_time_current_sec(); if (cdqb->dqb_bsoftlimit && toqb(cdqb->dqb_curspace) >= cdqb->dqb_bsoftlimit && @@ -2064,7 +2068,7 @@ static int __init fsfilt_ext3_init(void) int rc; fcb_cache = cfs_mem_cache_create("fsfilt_ext3_fcb", - sizeof(struct fsfilt_cb_data), 0, 0); + sizeof(struct fsfilt_cb_data), 0, 0); if (!fcb_cache) { CERROR("error allocating fsfilt journal callback cache\n"); GOTO(out, rc = -ENOMEM);