mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
Merge branch 'akpm' (patches from Andrew)
Merge updates from Andrew Morton: - a few misc things - ocfs2 updates - the v9fs maintainers have been missing for a long time. I've taken over v9fs patch slinging. - most of MM * emailed patches from Andrew Morton <[email protected]>: (116 commits) mm,oom_reaper: check for MMF_OOM_SKIP before complaining mm/ksm: fix interaction with THP mm/memblock.c: cast constant ULLONG_MAX to phys_addr_t headers: untangle kmemleak.h from mm.h include/linux/mmdebug.h: make VM_WARN* non-rvals mm/page_isolation.c: make start_isolate_page_range() fail if already isolated mm: change return type to vm_fault_t mm, oom: remove 3% bonus for CAP_SYS_ADMIN processes mm, page_alloc: wakeup kcompactd even if kswapd cannot free more memory kernel/fork.c: detect early free of a live mm mm: make counting of list_lru_one::nr_items lockless mm/swap_state.c: make bool enable_vma_readahead and swap_vma_readahead() static block_invalidatepage(): only release page if the full page was invalidated mm: kernel-doc: add missing parameter descriptions mm/swap.c: remove @cold parameter description for release_pages() mm/nommu: remove description of alloc_vm_area zram: drop max_zpage_size and use zs_huge_class_size() zsmalloc: introduce zs_huge_class_size() mm: fix races between swapoff and flush dcache fs/direct-io.c: minor cleanups in do_blockdev_direct_IO ...
This commit is contained in:
commit
3b54765cca
151 changed files with 1601 additions and 1269 deletions
|
|
@ -292,6 +292,10 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
|
|||
#ifdef CONFIG_9P_FSCACHE
|
||||
kfree(v9ses->cachetag);
|
||||
v9ses->cachetag = match_strdup(&args[0]);
|
||||
if (!v9ses->cachetag) {
|
||||
ret = -ENOMEM;
|
||||
goto free_and_return;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case Opt_cache:
|
||||
|
|
@ -471,6 +475,9 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
|
|||
return fid;
|
||||
|
||||
err_clnt:
|
||||
#ifdef CONFIG_9P_FSCACHE
|
||||
kfree(v9ses->cachetag);
|
||||
#endif
|
||||
p9_client_destroy(v9ses->clnt);
|
||||
err_names:
|
||||
kfree(v9ses->uname);
|
||||
|
|
|
|||
|
|
@ -578,6 +578,24 @@ static int v9fs_at_to_dotl_flags(int flags)
|
|||
return rflags;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_dec_count - helper functon to drop i_nlink.
|
||||
*
|
||||
* If a directory had nlink <= 2 (including . and ..), then we should not drop
|
||||
* the link count, which indicates the underlying exported fs doesn't maintain
|
||||
* nlink accurately. e.g.
|
||||
* - overlayfs sets nlink to 1 for merged dir
|
||||
* - ext4 (with dir_nlink feature enabled) sets nlink to 1 if a dir has more
|
||||
* than EXT4_LINK_MAX (65000) links.
|
||||
*
|
||||
* @inode: inode whose nlink is being dropped
|
||||
*/
|
||||
static void v9fs_dec_count(struct inode *inode)
|
||||
{
|
||||
if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
|
||||
drop_nlink(inode);
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_remove - helper function to remove files and directories
|
||||
* @dir: directory inode that is being deleted
|
||||
|
|
@ -621,9 +639,9 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
|
|||
*/
|
||||
if (flags & AT_REMOVEDIR) {
|
||||
clear_nlink(inode);
|
||||
drop_nlink(dir);
|
||||
v9fs_dec_count(dir);
|
||||
} else
|
||||
drop_nlink(inode);
|
||||
v9fs_dec_count(inode);
|
||||
|
||||
v9fs_invalidate_inode_attr(inode);
|
||||
v9fs_invalidate_inode_attr(dir);
|
||||
|
|
@ -1024,12 +1042,12 @@ clunk_newdir:
|
|||
if (S_ISDIR(new_inode->i_mode))
|
||||
clear_nlink(new_inode);
|
||||
else
|
||||
drop_nlink(new_inode);
|
||||
v9fs_dec_count(new_inode);
|
||||
}
|
||||
if (S_ISDIR(old_inode->i_mode)) {
|
||||
if (!new_inode)
|
||||
inc_nlink(new_dir);
|
||||
drop_nlink(old_dir);
|
||||
v9fs_dec_count(old_dir);
|
||||
}
|
||||
v9fs_invalidate_inode_attr(old_inode);
|
||||
v9fs_invalidate_inode_attr(old_dir);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
|
|||
if (v9ses->cache)
|
||||
sb->s_bdi->ra_pages = (VM_MAX_READAHEAD * 1024)/PAGE_SIZE;
|
||||
|
||||
sb->s_flags |= SB_ACTIVE | SB_DIRSYNC | SB_NOATIME;
|
||||
sb->s_flags |= SB_ACTIVE | SB_DIRSYNC;
|
||||
if (!v9ses->cache)
|
||||
sb->s_flags |= SB_SYNCHRONOUS;
|
||||
|
||||
|
|
|
|||
|
|
@ -1324,7 +1324,8 @@ static void flush_disk(struct block_device *bdev, bool kill_dirty)
|
|||
* @bdev: struct bdev to adjust.
|
||||
*
|
||||
* This routine checks to see if the bdev size does not match the disk size
|
||||
* and adjusts it if it differs.
|
||||
* and adjusts it if it differs. When shrinking the bdev size, its all caches
|
||||
* are freed.
|
||||
*/
|
||||
void check_disk_size_change(struct gendisk *disk, struct block_device *bdev)
|
||||
{
|
||||
|
|
@ -1337,7 +1338,8 @@ void check_disk_size_change(struct gendisk *disk, struct block_device *bdev)
|
|||
"%s: detected capacity change from %lld to %lld\n",
|
||||
disk->disk_name, bdev_size, disk_size);
|
||||
i_size_write(bdev->bd_inode, disk_size);
|
||||
flush_disk(bdev, false);
|
||||
if (bdev_size > disk_size)
|
||||
flush_disk(bdev, false);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(check_disk_size_change);
|
||||
|
|
|
|||
|
|
@ -1511,7 +1511,7 @@ void block_invalidatepage(struct page *page, unsigned int offset,
|
|||
* The get_block cached value has been unconditionally invalidated,
|
||||
* so real IO is not possible anymore.
|
||||
*/
|
||||
if (offset == 0)
|
||||
if (length == PAGE_SIZE)
|
||||
try_to_release_page(page, 0);
|
||||
out:
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1177,9 +1177,9 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
|
|||
unsigned blkbits = i_blkbits;
|
||||
unsigned blocksize_mask = (1 << blkbits) - 1;
|
||||
ssize_t retval = -EINVAL;
|
||||
size_t count = iov_iter_count(iter);
|
||||
const size_t count = iov_iter_count(iter);
|
||||
loff_t offset = iocb->ki_pos;
|
||||
loff_t end = offset + count;
|
||||
const loff_t end = offset + count;
|
||||
struct dio *dio;
|
||||
struct dio_submit sdio = { 0, };
|
||||
struct buffer_head map_bh = { 0, };
|
||||
|
|
@ -1200,7 +1200,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
|
|||
}
|
||||
|
||||
/* watch out for a 0 len io from a tricksy fs */
|
||||
if (iov_iter_rw(iter) == READ && !iov_iter_count(iter))
|
||||
if (iov_iter_rw(iter) == READ && !count)
|
||||
return 0;
|
||||
|
||||
dio = kmem_cache_alloc(dio_cache, GFP_KERNEL);
|
||||
|
|
@ -1315,8 +1315,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
|
|||
|
||||
dio->should_dirty = (iter->type == ITER_IOVEC);
|
||||
sdio.iter = iter;
|
||||
sdio.final_block_in_request =
|
||||
(offset + iov_iter_count(iter)) >> blkbits;
|
||||
sdio.final_block_in_request = end >> blkbits;
|
||||
|
||||
/*
|
||||
* In case of non-aligned buffers, we may need 2 more
|
||||
|
|
|
|||
|
|
@ -138,10 +138,14 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
|
||||
/*
|
||||
* page based offset in vm_pgoff could be sufficiently large to
|
||||
* overflow a (l)off_t when converted to byte offset.
|
||||
* overflow a loff_t when converted to byte offset. This can
|
||||
* only happen on architectures where sizeof(loff_t) ==
|
||||
* sizeof(unsigned long). So, only check in those instances.
|
||||
*/
|
||||
if (vma->vm_pgoff & PGOFF_LOFFT_MAX)
|
||||
return -EINVAL;
|
||||
if (sizeof(unsigned long) == sizeof(loff_t)) {
|
||||
if (vma->vm_pgoff & PGOFF_LOFFT_MAX)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* must be huge page aligned */
|
||||
if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
|
||||
|
|
|
|||
|
|
@ -7119,7 +7119,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
|
|||
goto out_commit;
|
||||
did_quota = 1;
|
||||
|
||||
data_ac->ac_resv = &OCFS2_I(inode)->ip_la_data_resv;
|
||||
data_ac->ac_resv = &oi->ip_la_data_resv;
|
||||
|
||||
ret = ocfs2_claim_clusters(handle, data_ac, 1, &bit_off,
|
||||
&num);
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ static int ocfs2_readpage(struct file *file, struct page *page)
|
|||
unlock = 0;
|
||||
|
||||
out_alloc:
|
||||
up_read(&OCFS2_I(inode)->ip_alloc_sem);
|
||||
up_read(&oi->ip_alloc_sem);
|
||||
out_inode_unlock:
|
||||
ocfs2_inode_unlock(inode, 0);
|
||||
out:
|
||||
|
|
@ -2213,7 +2213,7 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock,
|
|||
down_write(&oi->ip_alloc_sem);
|
||||
|
||||
if (first_get_block) {
|
||||
if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
|
||||
if (ocfs2_sparse_alloc(osb))
|
||||
ret = ocfs2_zero_tail(inode, di_bh, pos);
|
||||
else
|
||||
ret = ocfs2_expand_nonsparse_inode(inode, di_bh, pos,
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level)
|
|||
/*
|
||||
* Using a named enum representing lock types in terms of #N bit stored in
|
||||
* iocb->private, which is going to be used for communication between
|
||||
* ocfs2_dio_end_io() and ocfs2_file_aio_write/read().
|
||||
* ocfs2_dio_end_io() and ocfs2_file_write/read_iter().
|
||||
*/
|
||||
enum ocfs2_iocb_lock_bits {
|
||||
OCFS2_IOCB_RW_LOCK = 0,
|
||||
|
|
|
|||
|
|
@ -570,7 +570,16 @@ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,
|
|||
current_page, vec_len, vec_start);
|
||||
|
||||
len = bio_add_page(bio, page, vec_len, vec_start);
|
||||
if (len != vec_len) break;
|
||||
if (len != vec_len) {
|
||||
mlog(ML_ERROR, "Adding page[%d] to bio failed, "
|
||||
"page %p, len %d, vec_len %u, vec_start %u, "
|
||||
"bi_sector %llu\n", current_page, page, len,
|
||||
vec_len, vec_start,
|
||||
(unsigned long long)bio->bi_iter.bi_sector);
|
||||
bio_put(bio);
|
||||
bio = ERR_PTR(-EIO);
|
||||
return bio;
|
||||
}
|
||||
|
||||
cs += vec_len / (PAGE_SIZE/spp);
|
||||
vec_start = 0;
|
||||
|
|
|
|||
|
|
@ -3072,7 +3072,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
|
|||
* We need to return the correct block within the
|
||||
* cluster which should hold our entry.
|
||||
*/
|
||||
off = ocfs2_dx_dir_hash_idx(OCFS2_SB(dir->i_sb),
|
||||
off = ocfs2_dx_dir_hash_idx(osb,
|
||||
&lookup->dl_hinfo);
|
||||
get_bh(dx_leaves[off]);
|
||||
lookup->dl_dx_leaf_bh = dx_leaves[off];
|
||||
|
|
|
|||
|
|
@ -224,14 +224,12 @@ void dlm_do_local_ast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
|
|||
struct dlm_lock *lock)
|
||||
{
|
||||
dlm_astlockfunc_t *fn;
|
||||
struct dlm_lockstatus *lksb;
|
||||
|
||||
mlog(0, "%s: res %.*s, lock %u:%llu, Local AST\n", dlm->name,
|
||||
res->lockname.len, res->lockname.name,
|
||||
dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
|
||||
dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)));
|
||||
|
||||
lksb = lock->lksb;
|
||||
fn = lock->ast;
|
||||
BUG_ON(lock->ml.node != dlm->node_num);
|
||||
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ struct dlm_ctxt
|
|||
u8 node_num;
|
||||
u32 key;
|
||||
u8 joining_node;
|
||||
u8 migrate_done; /* set to 1 means node has migrated all lock resources */
|
||||
wait_queue_head_t dlm_join_events;
|
||||
unsigned long live_nodes_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
|
||||
unsigned long domain_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
|
||||
|
|
@ -960,13 +961,10 @@ static inline int dlm_send_proxy_ast(struct dlm_ctxt *dlm,
|
|||
void dlm_print_one_lock_resource(struct dlm_lock_resource *res);
|
||||
void __dlm_print_one_lock_resource(struct dlm_lock_resource *res);
|
||||
|
||||
u8 dlm_nm_this_node(struct dlm_ctxt *dlm);
|
||||
void dlm_kick_thread(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
|
||||
void __dlm_dirty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
|
||||
|
||||
|
||||
int dlm_nm_init(struct dlm_ctxt *dlm);
|
||||
int dlm_heartbeat_init(struct dlm_ctxt *dlm);
|
||||
void dlm_hb_node_down_cb(struct o2nm_node *node, int idx, void *data);
|
||||
void dlm_hb_node_up_cb(struct o2nm_node *node, int idx, void *data);
|
||||
|
||||
|
|
|
|||
|
|
@ -461,6 +461,19 @@ redo_bucket:
|
|||
cond_resched_lock(&dlm->spinlock);
|
||||
num += n;
|
||||
}
|
||||
|
||||
if (!num) {
|
||||
if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) {
|
||||
mlog(0, "%s: perhaps there are more lock resources "
|
||||
"need to be migrated after dlm recovery\n", dlm->name);
|
||||
ret = -EAGAIN;
|
||||
} else {
|
||||
mlog(0, "%s: we won't do dlm recovery after migrating "
|
||||
"all lock resources\n", dlm->name);
|
||||
dlm->migrate_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&dlm->spinlock);
|
||||
wake_up(&dlm->dlm_thread_wq);
|
||||
|
||||
|
|
@ -675,20 +688,6 @@ static void dlm_leave_domain(struct dlm_ctxt *dlm)
|
|||
spin_unlock(&dlm->spinlock);
|
||||
}
|
||||
|
||||
int dlm_shutting_down(struct dlm_ctxt *dlm)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
spin_lock(&dlm_domain_lock);
|
||||
|
||||
if (dlm->dlm_state == DLM_CTXT_IN_SHUTDOWN)
|
||||
ret = 1;
|
||||
|
||||
spin_unlock(&dlm_domain_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dlm_unregister_domain(struct dlm_ctxt *dlm)
|
||||
{
|
||||
int leave = 0;
|
||||
|
|
@ -2052,6 +2051,8 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
|
|||
dlm->joining_node = DLM_LOCK_RES_OWNER_UNKNOWN;
|
||||
init_waitqueue_head(&dlm->dlm_join_events);
|
||||
|
||||
dlm->migrate_done = 0;
|
||||
|
||||
dlm->reco.new_master = O2NM_INVALID_NODE_NUM;
|
||||
dlm->reco.dead_node = O2NM_INVALID_NODE_NUM;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,30 @@
|
|||
extern spinlock_t dlm_domain_lock;
|
||||
extern struct list_head dlm_domains;
|
||||
|
||||
int dlm_shutting_down(struct dlm_ctxt *dlm);
|
||||
static inline int dlm_joined(struct dlm_ctxt *dlm)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
spin_lock(&dlm_domain_lock);
|
||||
if (dlm->dlm_state == DLM_CTXT_JOINED)
|
||||
ret = 1;
|
||||
spin_unlock(&dlm_domain_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int dlm_shutting_down(struct dlm_ctxt *dlm)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
spin_lock(&dlm_domain_lock);
|
||||
if (dlm->dlm_state == DLM_CTXT_IN_SHUTDOWN)
|
||||
ret = 1;
|
||||
spin_unlock(&dlm_domain_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dlm_fire_domain_eviction_callbacks(struct dlm_ctxt *dlm,
|
||||
int node_num);
|
||||
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ int dlm_init_lock_cache(void)
|
|||
|
||||
void dlm_destroy_lock_cache(void)
|
||||
{
|
||||
if (dlm_lock_cache)
|
||||
kmem_cache_destroy(dlm_lock_cache);
|
||||
kmem_cache_destroy(dlm_lock_cache);
|
||||
}
|
||||
|
||||
/* Tell us whether we can grant a new lock request.
|
||||
|
|
|
|||
|
|
@ -414,8 +414,7 @@ int dlm_init_mle_cache(void)
|
|||
|
||||
void dlm_destroy_mle_cache(void)
|
||||
{
|
||||
if (dlm_mle_cache)
|
||||
kmem_cache_destroy(dlm_mle_cache);
|
||||
kmem_cache_destroy(dlm_mle_cache);
|
||||
}
|
||||
|
||||
static void dlm_mle_release(struct kref *kref)
|
||||
|
|
@ -472,15 +471,11 @@ bail:
|
|||
|
||||
void dlm_destroy_master_caches(void)
|
||||
{
|
||||
if (dlm_lockname_cache) {
|
||||
kmem_cache_destroy(dlm_lockname_cache);
|
||||
dlm_lockname_cache = NULL;
|
||||
}
|
||||
kmem_cache_destroy(dlm_lockname_cache);
|
||||
dlm_lockname_cache = NULL;
|
||||
|
||||
if (dlm_lockres_cache) {
|
||||
kmem_cache_destroy(dlm_lockres_cache);
|
||||
dlm_lockres_cache = NULL;
|
||||
}
|
||||
kmem_cache_destroy(dlm_lockres_cache);
|
||||
dlm_lockres_cache = NULL;
|
||||
}
|
||||
|
||||
static void dlm_lockres_release(struct kref *kref)
|
||||
|
|
@ -2495,13 +2490,13 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
|
|||
}
|
||||
|
||||
/*
|
||||
* A migrateable resource is one that is :
|
||||
* A migratable resource is one that is :
|
||||
* 1. locally mastered, and,
|
||||
* 2. zero local locks, and,
|
||||
* 3. one or more non-local locks, or, one or more references
|
||||
* Returns 1 if yes, 0 if not.
|
||||
*/
|
||||
static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
|
||||
static int dlm_is_lockres_migratable(struct dlm_ctxt *dlm,
|
||||
struct dlm_lock_resource *res)
|
||||
{
|
||||
enum dlm_lockres_list idx;
|
||||
|
|
@ -2532,7 +2527,7 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
|
|||
continue;
|
||||
}
|
||||
cookie = be64_to_cpu(lock->ml.cookie);
|
||||
mlog(0, "%s: Not migrateable res %.*s, lock %u:%llu on "
|
||||
mlog(0, "%s: Not migratable res %.*s, lock %u:%llu on "
|
||||
"%s list\n", dlm->name, res->lockname.len,
|
||||
res->lockname.name,
|
||||
dlm_get_lock_cookie_node(cookie),
|
||||
|
|
@ -2548,7 +2543,7 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
mlog(0, "%s: res %.*s, Migrateable\n", dlm->name, res->lockname.len,
|
||||
mlog(0, "%s: res %.*s, Migratable\n", dlm->name, res->lockname.len,
|
||||
res->lockname.name);
|
||||
|
||||
return 1;
|
||||
|
|
@ -2792,7 +2787,7 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
|
|||
assert_spin_locked(&dlm->spinlock);
|
||||
|
||||
spin_lock(&res->spinlock);
|
||||
if (dlm_is_lockres_migrateable(dlm, res))
|
||||
if (dlm_is_lockres_migratable(dlm, res))
|
||||
target = dlm_pick_migration_target(dlm, res);
|
||||
spin_unlock(&res->spinlock);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node);
|
|||
static int dlm_init_recovery_area(struct dlm_ctxt *dlm, u8 dead_node);
|
||||
static int dlm_request_all_locks(struct dlm_ctxt *dlm,
|
||||
u8 request_from, u8 dead_node);
|
||||
static void dlm_destroy_recovery_area(struct dlm_ctxt *dlm, u8 dead_node);
|
||||
static void dlm_destroy_recovery_area(struct dlm_ctxt *dlm);
|
||||
|
||||
static inline int dlm_num_locks_in_lockres(struct dlm_lock_resource *res);
|
||||
static void dlm_init_migratable_lockres(struct dlm_migratable_lockres *mres,
|
||||
|
|
@ -423,12 +423,11 @@ void dlm_wait_for_recovery(struct dlm_ctxt *dlm)
|
|||
|
||||
static void dlm_begin_recovery(struct dlm_ctxt *dlm)
|
||||
{
|
||||
spin_lock(&dlm->spinlock);
|
||||
assert_spin_locked(&dlm->spinlock);
|
||||
BUG_ON(dlm->reco.state & DLM_RECO_STATE_ACTIVE);
|
||||
printk(KERN_NOTICE "o2dlm: Begin recovery on domain %s for node %u\n",
|
||||
dlm->name, dlm->reco.dead_node);
|
||||
dlm->reco.state |= DLM_RECO_STATE_ACTIVE;
|
||||
spin_unlock(&dlm->spinlock);
|
||||
}
|
||||
|
||||
static void dlm_end_recovery(struct dlm_ctxt *dlm)
|
||||
|
|
@ -456,6 +455,13 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
|
|||
|
||||
spin_lock(&dlm->spinlock);
|
||||
|
||||
if (dlm->migrate_done) {
|
||||
mlog(0, "%s: no need do recovery after migrating all "
|
||||
"lock resources\n", dlm->name);
|
||||
spin_unlock(&dlm->spinlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check to see if the new master has died */
|
||||
if (dlm->reco.new_master != O2NM_INVALID_NODE_NUM &&
|
||||
test_bit(dlm->reco.new_master, dlm->recovery_map)) {
|
||||
|
|
@ -490,12 +496,13 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
|
|||
mlog(0, "%s(%d):recovery thread found node %u in the recovery map!\n",
|
||||
dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
|
||||
dlm->reco.dead_node);
|
||||
spin_unlock(&dlm->spinlock);
|
||||
|
||||
/* take write barrier */
|
||||
/* (stops the list reshuffling thread, proxy ast handling) */
|
||||
dlm_begin_recovery(dlm);
|
||||
|
||||
spin_unlock(&dlm->spinlock);
|
||||
|
||||
if (dlm->reco.new_master == dlm->node_num)
|
||||
goto master_here;
|
||||
|
||||
|
|
@ -739,7 +746,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
|
|||
}
|
||||
|
||||
if (destroy)
|
||||
dlm_destroy_recovery_area(dlm, dead_node);
|
||||
dlm_destroy_recovery_area(dlm);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
@ -764,7 +771,7 @@ static int dlm_init_recovery_area(struct dlm_ctxt *dlm, u8 dead_node)
|
|||
|
||||
ndata = kzalloc(sizeof(*ndata), GFP_NOFS);
|
||||
if (!ndata) {
|
||||
dlm_destroy_recovery_area(dlm, dead_node);
|
||||
dlm_destroy_recovery_area(dlm);
|
||||
return -ENOMEM;
|
||||
}
|
||||
ndata->node_num = num;
|
||||
|
|
@ -778,7 +785,7 @@ static int dlm_init_recovery_area(struct dlm_ctxt *dlm, u8 dead_node)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dlm_destroy_recovery_area(struct dlm_ctxt *dlm, u8 dead_node)
|
||||
static void dlm_destroy_recovery_area(struct dlm_ctxt *dlm)
|
||||
{
|
||||
struct dlm_reco_node_data *ndata, *next;
|
||||
LIST_HEAD(tmplist);
|
||||
|
|
@ -1378,6 +1385,15 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
|
|||
if (!dlm_grab(dlm))
|
||||
return -EINVAL;
|
||||
|
||||
if (!dlm_joined(dlm)) {
|
||||
mlog(ML_ERROR, "Domain %s not joined! "
|
||||
"lockres %.*s, master %u\n",
|
||||
dlm->name, mres->lockname_len,
|
||||
mres->lockname, mres->master);
|
||||
dlm_put(dlm);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
BUG_ON(!(mres->flags & (DLM_MRES_RECOVERY|DLM_MRES_MIGRATION)));
|
||||
|
||||
real_master = mres->master;
|
||||
|
|
@ -1807,7 +1823,6 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
|
|||
int i, j, bad;
|
||||
struct dlm_lock *lock;
|
||||
u8 from = O2NM_MAX_NODES;
|
||||
unsigned int added = 0;
|
||||
__be64 c;
|
||||
|
||||
mlog(0, "running %d locks for this lockres\n", mres->num_locks);
|
||||
|
|
@ -1823,7 +1838,6 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
|
|||
spin_lock(&res->spinlock);
|
||||
dlm_lockres_set_refmap_bit(dlm, res, from);
|
||||
spin_unlock(&res->spinlock);
|
||||
added++;
|
||||
break;
|
||||
}
|
||||
BUG_ON(ml->highest_blocked != LKM_IVMODE);
|
||||
|
|
@ -1911,7 +1925,6 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
|
|||
/* do not alter lock refcount. switching lists. */
|
||||
list_move_tail(&lock->list, queue);
|
||||
spin_unlock(&res->spinlock);
|
||||
added++;
|
||||
|
||||
mlog(0, "just reordered a local lock!\n");
|
||||
continue;
|
||||
|
|
@ -2037,7 +2050,6 @@ skip_lvb:
|
|||
"setting refmap bit\n", dlm->name,
|
||||
res->lockname.len, res->lockname.name, ml->node);
|
||||
dlm_lockres_set_refmap_bit(dlm, res, ml->node);
|
||||
added++;
|
||||
}
|
||||
spin_unlock(&res->spinlock);
|
||||
}
|
||||
|
|
@ -2331,13 +2343,6 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm,
|
|||
__dlm_dirty_lockres(dlm, res);
|
||||
}
|
||||
|
||||
/* if this node is the recovery master, and there are no
|
||||
* locks for a given lockres owned by this node that are in
|
||||
* either PR or EX mode, zero out the lvb before requesting.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node)
|
||||
{
|
||||
struct dlm_lock_resource *res;
|
||||
|
|
|
|||
|
|
@ -1756,8 +1756,7 @@ int ocfs2_rw_lock(struct inode *inode, int write)
|
|||
|
||||
level = write ? DLM_LOCK_EX : DLM_LOCK_PR;
|
||||
|
||||
status = ocfs2_cluster_lock(OCFS2_SB(inode->i_sb), lockres, level, 0,
|
||||
0);
|
||||
status = ocfs2_cluster_lock(osb, lockres, level, 0, 0);
|
||||
if (status < 0)
|
||||
mlog_errno(status);
|
||||
|
||||
|
|
@ -1796,7 +1795,7 @@ void ocfs2_rw_unlock(struct inode *inode, int write)
|
|||
write ? "EXMODE" : "PRMODE");
|
||||
|
||||
if (!ocfs2_mount_local(osb))
|
||||
ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
|
||||
ocfs2_cluster_unlock(osb, lockres, level);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1816,8 +1815,7 @@ int ocfs2_open_lock(struct inode *inode)
|
|||
|
||||
lockres = &OCFS2_I(inode)->ip_open_lockres;
|
||||
|
||||
status = ocfs2_cluster_lock(OCFS2_SB(inode->i_sb), lockres,
|
||||
DLM_LOCK_PR, 0, 0);
|
||||
status = ocfs2_cluster_lock(osb, lockres, DLM_LOCK_PR, 0, 0);
|
||||
if (status < 0)
|
||||
mlog_errno(status);
|
||||
|
||||
|
|
@ -1854,8 +1852,7 @@ int ocfs2_try_open_lock(struct inode *inode, int write)
|
|||
* other nodes and the -EAGAIN will indicate to the caller that
|
||||
* this inode is still in use.
|
||||
*/
|
||||
status = ocfs2_cluster_lock(OCFS2_SB(inode->i_sb), lockres,
|
||||
level, DLM_LKF_NOQUEUE, 0);
|
||||
status = ocfs2_cluster_lock(osb, lockres, level, DLM_LKF_NOQUEUE, 0);
|
||||
|
||||
out:
|
||||
return status;
|
||||
|
|
@ -1876,11 +1873,9 @@ void ocfs2_open_unlock(struct inode *inode)
|
|||
goto out;
|
||||
|
||||
if(lockres->l_ro_holders)
|
||||
ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres,
|
||||
DLM_LOCK_PR);
|
||||
ocfs2_cluster_unlock(osb, lockres, DLM_LOCK_PR);
|
||||
if(lockres->l_ex_holders)
|
||||
ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres,
|
||||
DLM_LOCK_EX);
|
||||
ocfs2_cluster_unlock(osb, lockres, DLM_LOCK_EX);
|
||||
|
||||
out:
|
||||
return;
|
||||
|
|
@ -2601,9 +2596,9 @@ void ocfs2_inode_unlock(struct inode *inode,
|
|||
(unsigned long long)OCFS2_I(inode)->ip_blkno,
|
||||
ex ? "EXMODE" : "PRMODE");
|
||||
|
||||
if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) &&
|
||||
if (!ocfs2_is_hard_readonly(osb) &&
|
||||
!ocfs2_mount_local(osb))
|
||||
ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
|
||||
ocfs2_cluster_unlock(osb, lockres, level);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ static int ocfs2_file_open(struct inode *inode, struct file *file)
|
|||
struct ocfs2_inode_info *oi = OCFS2_I(inode);
|
||||
|
||||
trace_ocfs2_file_open(inode, file, file->f_path.dentry,
|
||||
(unsigned long long)OCFS2_I(inode)->ip_blkno,
|
||||
(unsigned long long)oi->ip_blkno,
|
||||
file->f_path.dentry->d_name.len,
|
||||
file->f_path.dentry->d_name.name, mode);
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ static int ocfs2_file_open(struct inode *inode, struct file *file)
|
|||
/* Check that the inode hasn't been wiped from disk by another
|
||||
* node. If it hasn't then we're safe as long as we hold the
|
||||
* spin lock until our increment of open count. */
|
||||
if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
|
||||
if (oi->ip_flags & OCFS2_INODE_DELETED) {
|
||||
spin_unlock(&oi->ip_lock);
|
||||
|
||||
status = -ENOENT;
|
||||
|
|
@ -190,7 +190,7 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end,
|
|||
bool needs_barrier = false;
|
||||
|
||||
trace_ocfs2_sync_file(inode, file, file->f_path.dentry,
|
||||
OCFS2_I(inode)->ip_blkno,
|
||||
oi->ip_blkno,
|
||||
file->f_path.dentry->d_name.len,
|
||||
file->f_path.dentry->d_name.name,
|
||||
(unsigned long long)datasync);
|
||||
|
|
@ -296,7 +296,7 @@ int ocfs2_update_inode_atime(struct inode *inode,
|
|||
ocfs2_journal_dirty(handle, bh);
|
||||
|
||||
out_commit:
|
||||
ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
|
||||
ocfs2_commit_trans(osb, handle);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2257,7 +2257,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
|
|||
int direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0;
|
||||
int nowait = iocb->ki_flags & IOCB_NOWAIT ? 1 : 0;
|
||||
|
||||
trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry,
|
||||
trace_ocfs2_file_write_iter(inode, file, file->f_path.dentry,
|
||||
(unsigned long long)OCFS2_I(inode)->ip_blkno,
|
||||
file->f_path.dentry->d_name.len,
|
||||
file->f_path.dentry->d_name.name,
|
||||
|
|
@ -2405,7 +2405,7 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb,
|
|||
int direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0;
|
||||
int nowait = iocb->ki_flags & IOCB_NOWAIT ? 1 : 0;
|
||||
|
||||
trace_ocfs2_file_aio_read(inode, filp, filp->f_path.dentry,
|
||||
trace_ocfs2_file_read_iter(inode, filp, filp->f_path.dentry,
|
||||
(unsigned long long)OCFS2_I(inode)->ip_blkno,
|
||||
filp->f_path.dentry->d_name.len,
|
||||
filp->f_path.dentry->d_name.name,
|
||||
|
|
@ -2448,7 +2448,7 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb,
|
|||
*
|
||||
* Take and drop the meta data lock to update inode fields
|
||||
* like i_size. This allows the checks down below
|
||||
* generic_file_aio_read() a chance of actually working.
|
||||
* generic_file_read_iter() a chance of actually working.
|
||||
*/
|
||||
ret = ocfs2_inode_lock_atime(inode, filp->f_path.mnt, &lock_level,
|
||||
!nowait);
|
||||
|
|
@ -2460,7 +2460,7 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb,
|
|||
ocfs2_inode_unlock(inode, lock_level);
|
||||
|
||||
ret = generic_file_read_iter(iocb, to);
|
||||
trace_generic_file_aio_read_ret(ret);
|
||||
trace_generic_file_read_iter_ret(ret);
|
||||
|
||||
/* buffered aio wouldn't have proper lock coverage today */
|
||||
BUG_ON(ret == -EIOCBQUEUED && !(iocb->ki_flags & IOCB_DIRECT));
|
||||
|
|
|
|||
|
|
@ -53,36 +53,6 @@ static const char * const ocfs2_filecheck_errs[] = {
|
|||
"UNSUPPORTED"
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(ocfs2_filecheck_sysfs_lock);
|
||||
static LIST_HEAD(ocfs2_filecheck_sysfs_list);
|
||||
|
||||
struct ocfs2_filecheck {
|
||||
struct list_head fc_head; /* File check entry list head */
|
||||
spinlock_t fc_lock;
|
||||
unsigned int fc_max; /* Maximum number of entry in list */
|
||||
unsigned int fc_size; /* Current entry count in list */
|
||||
unsigned int fc_done; /* Finished entry count in list */
|
||||
};
|
||||
|
||||
struct ocfs2_filecheck_sysfs_entry { /* sysfs entry per mounting */
|
||||
struct list_head fs_list;
|
||||
atomic_t fs_count;
|
||||
struct super_block *fs_sb;
|
||||
struct kset *fs_devicekset;
|
||||
struct kset *fs_fcheckkset;
|
||||
struct ocfs2_filecheck *fs_fcheck;
|
||||
};
|
||||
|
||||
#define OCFS2_FILECHECK_MAXSIZE 100
|
||||
#define OCFS2_FILECHECK_MINSIZE 10
|
||||
|
||||
/* File check operation type */
|
||||
enum {
|
||||
OCFS2_FILECHECK_TYPE_CHK = 0, /* Check a file(inode) */
|
||||
OCFS2_FILECHECK_TYPE_FIX, /* Fix a file(inode) */
|
||||
OCFS2_FILECHECK_TYPE_SET = 100 /* Set entry list maximum size */
|
||||
};
|
||||
|
||||
struct ocfs2_filecheck_entry {
|
||||
struct list_head fe_list;
|
||||
unsigned long fe_ino;
|
||||
|
|
@ -110,35 +80,84 @@ ocfs2_filecheck_error(int errno)
|
|||
return ocfs2_filecheck_errs[errno - OCFS2_FILECHECK_ERR_START + 1];
|
||||
}
|
||||
|
||||
static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
char *buf);
|
||||
static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
static struct kobj_attribute ocfs2_attr_filecheck_chk =
|
||||
static ssize_t ocfs2_filecheck_attr_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
char *buf);
|
||||
static ssize_t ocfs2_filecheck_attr_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
static struct kobj_attribute ocfs2_filecheck_attr_chk =
|
||||
__ATTR(check, S_IRUSR | S_IWUSR,
|
||||
ocfs2_filecheck_show,
|
||||
ocfs2_filecheck_store);
|
||||
static struct kobj_attribute ocfs2_attr_filecheck_fix =
|
||||
ocfs2_filecheck_attr_show,
|
||||
ocfs2_filecheck_attr_store);
|
||||
static struct kobj_attribute ocfs2_filecheck_attr_fix =
|
||||
__ATTR(fix, S_IRUSR | S_IWUSR,
|
||||
ocfs2_filecheck_show,
|
||||
ocfs2_filecheck_store);
|
||||
static struct kobj_attribute ocfs2_attr_filecheck_set =
|
||||
ocfs2_filecheck_attr_show,
|
||||
ocfs2_filecheck_attr_store);
|
||||
static struct kobj_attribute ocfs2_filecheck_attr_set =
|
||||
__ATTR(set, S_IRUSR | S_IWUSR,
|
||||
ocfs2_filecheck_show,
|
||||
ocfs2_filecheck_store);
|
||||
ocfs2_filecheck_attr_show,
|
||||
ocfs2_filecheck_attr_store);
|
||||
static struct attribute *ocfs2_filecheck_attrs[] = {
|
||||
&ocfs2_filecheck_attr_chk.attr,
|
||||
&ocfs2_filecheck_attr_fix.attr,
|
||||
&ocfs2_filecheck_attr_set.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void ocfs2_filecheck_release(struct kobject *kobj)
|
||||
{
|
||||
struct ocfs2_filecheck_sysfs_entry *entry = container_of(kobj,
|
||||
struct ocfs2_filecheck_sysfs_entry, fs_kobj);
|
||||
|
||||
complete(&entry->fs_kobj_unregister);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ocfs2_filecheck_show(struct kobject *kobj, struct attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t ret = -EIO;
|
||||
struct kobj_attribute *kattr = container_of(attr,
|
||||
struct kobj_attribute, attr);
|
||||
|
||||
kobject_get(kobj);
|
||||
if (kattr->show)
|
||||
ret = kattr->show(kobj, kattr, buf);
|
||||
kobject_put(kobj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ocfs2_filecheck_store(struct kobject *kobj, struct attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
ssize_t ret = -EIO;
|
||||
struct kobj_attribute *kattr = container_of(attr,
|
||||
struct kobj_attribute, attr);
|
||||
|
||||
kobject_get(kobj);
|
||||
if (kattr->store)
|
||||
ret = kattr->store(kobj, kattr, buf, count);
|
||||
kobject_put(kobj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct sysfs_ops ocfs2_filecheck_ops = {
|
||||
.show = ocfs2_filecheck_show,
|
||||
.store = ocfs2_filecheck_store,
|
||||
};
|
||||
|
||||
static struct kobj_type ocfs2_ktype_filecheck = {
|
||||
.default_attrs = ocfs2_filecheck_attrs,
|
||||
.sysfs_ops = &ocfs2_filecheck_ops,
|
||||
.release = ocfs2_filecheck_release,
|
||||
};
|
||||
|
||||
static void
|
||||
ocfs2_filecheck_sysfs_free(struct ocfs2_filecheck_sysfs_entry *entry)
|
||||
{
|
||||
struct ocfs2_filecheck_entry *p;
|
||||
|
||||
if (!atomic_dec_and_test(&entry->fs_count)) {
|
||||
wait_var_event(&entry->fs_count,
|
||||
!atomic_read(&entry->fs_count));
|
||||
}
|
||||
|
||||
spin_lock(&entry->fs_fcheck->fc_lock);
|
||||
while (!list_empty(&entry->fs_fcheck->fc_head)) {
|
||||
p = list_first_entry(&entry->fs_fcheck->fc_head,
|
||||
|
|
@ -149,151 +168,48 @@ ocfs2_filecheck_sysfs_free(struct ocfs2_filecheck_sysfs_entry *entry)
|
|||
}
|
||||
spin_unlock(&entry->fs_fcheck->fc_lock);
|
||||
|
||||
kset_unregister(entry->fs_fcheckkset);
|
||||
kset_unregister(entry->fs_devicekset);
|
||||
kfree(entry->fs_fcheck);
|
||||
kfree(entry);
|
||||
entry->fs_fcheck = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ocfs2_filecheck_sysfs_add(struct ocfs2_filecheck_sysfs_entry *entry)
|
||||
int ocfs2_filecheck_create_sysfs(struct ocfs2_super *osb)
|
||||
{
|
||||
spin_lock(&ocfs2_filecheck_sysfs_lock);
|
||||
list_add_tail(&entry->fs_list, &ocfs2_filecheck_sysfs_list);
|
||||
spin_unlock(&ocfs2_filecheck_sysfs_lock);
|
||||
}
|
||||
|
||||
static int ocfs2_filecheck_sysfs_del(const char *devname)
|
||||
{
|
||||
struct ocfs2_filecheck_sysfs_entry *p;
|
||||
|
||||
spin_lock(&ocfs2_filecheck_sysfs_lock);
|
||||
list_for_each_entry(p, &ocfs2_filecheck_sysfs_list, fs_list) {
|
||||
if (!strcmp(p->fs_sb->s_id, devname)) {
|
||||
list_del(&p->fs_list);
|
||||
spin_unlock(&ocfs2_filecheck_sysfs_lock);
|
||||
ocfs2_filecheck_sysfs_free(p);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
spin_unlock(&ocfs2_filecheck_sysfs_lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ocfs2_filecheck_sysfs_put(struct ocfs2_filecheck_sysfs_entry *entry)
|
||||
{
|
||||
if (atomic_dec_and_test(&entry->fs_count))
|
||||
wake_up_var(&entry->fs_count);
|
||||
}
|
||||
|
||||
static struct ocfs2_filecheck_sysfs_entry *
|
||||
ocfs2_filecheck_sysfs_get(const char *devname)
|
||||
{
|
||||
struct ocfs2_filecheck_sysfs_entry *p = NULL;
|
||||
|
||||
spin_lock(&ocfs2_filecheck_sysfs_lock);
|
||||
list_for_each_entry(p, &ocfs2_filecheck_sysfs_list, fs_list) {
|
||||
if (!strcmp(p->fs_sb->s_id, devname)) {
|
||||
atomic_inc(&p->fs_count);
|
||||
spin_unlock(&ocfs2_filecheck_sysfs_lock);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
spin_unlock(&ocfs2_filecheck_sysfs_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ocfs2_filecheck_create_sysfs(struct super_block *sb)
|
||||
{
|
||||
int ret = 0;
|
||||
struct kset *device_kset = NULL;
|
||||
struct kset *fcheck_kset = NULL;
|
||||
struct ocfs2_filecheck *fcheck = NULL;
|
||||
struct ocfs2_filecheck_sysfs_entry *entry = NULL;
|
||||
struct attribute **attrs = NULL;
|
||||
struct attribute_group attrgp;
|
||||
|
||||
if (!ocfs2_kset)
|
||||
return -ENOMEM;
|
||||
|
||||
attrs = kmalloc(sizeof(struct attribute *) * 4, GFP_NOFS);
|
||||
if (!attrs) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
} else {
|
||||
attrs[0] = &ocfs2_attr_filecheck_chk.attr;
|
||||
attrs[1] = &ocfs2_attr_filecheck_fix.attr;
|
||||
attrs[2] = &ocfs2_attr_filecheck_set.attr;
|
||||
attrs[3] = NULL;
|
||||
memset(&attrgp, 0, sizeof(attrgp));
|
||||
attrgp.attrs = attrs;
|
||||
}
|
||||
int ret;
|
||||
struct ocfs2_filecheck *fcheck;
|
||||
struct ocfs2_filecheck_sysfs_entry *entry = &osb->osb_fc_ent;
|
||||
|
||||
fcheck = kmalloc(sizeof(struct ocfs2_filecheck), GFP_NOFS);
|
||||
if (!fcheck) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
} else {
|
||||
INIT_LIST_HEAD(&fcheck->fc_head);
|
||||
spin_lock_init(&fcheck->fc_lock);
|
||||
fcheck->fc_max = OCFS2_FILECHECK_MINSIZE;
|
||||
fcheck->fc_size = 0;
|
||||
fcheck->fc_done = 0;
|
||||
if (!fcheck)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&fcheck->fc_head);
|
||||
spin_lock_init(&fcheck->fc_lock);
|
||||
fcheck->fc_max = OCFS2_FILECHECK_MINSIZE;
|
||||
fcheck->fc_size = 0;
|
||||
fcheck->fc_done = 0;
|
||||
|
||||
entry->fs_kobj.kset = osb->osb_dev_kset;
|
||||
init_completion(&entry->fs_kobj_unregister);
|
||||
ret = kobject_init_and_add(&entry->fs_kobj, &ocfs2_ktype_filecheck,
|
||||
NULL, "filecheck");
|
||||
if (ret) {
|
||||
kfree(fcheck);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (strlen(sb->s_id) <= 0) {
|
||||
mlog(ML_ERROR,
|
||||
"Cannot get device basename when create filecheck sysfs\n");
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
device_kset = kset_create_and_add(sb->s_id, NULL, &ocfs2_kset->kobj);
|
||||
if (!device_kset) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
fcheck_kset = kset_create_and_add("filecheck", NULL,
|
||||
&device_kset->kobj);
|
||||
if (!fcheck_kset) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&fcheck_kset->kobj, &attrgp);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
entry = kmalloc(sizeof(struct ocfs2_filecheck_sysfs_entry), GFP_NOFS);
|
||||
if (!entry) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
} else {
|
||||
atomic_set(&entry->fs_count, 1);
|
||||
entry->fs_sb = sb;
|
||||
entry->fs_devicekset = device_kset;
|
||||
entry->fs_fcheckkset = fcheck_kset;
|
||||
entry->fs_fcheck = fcheck;
|
||||
ocfs2_filecheck_sysfs_add(entry);
|
||||
}
|
||||
|
||||
kfree(attrs);
|
||||
entry->fs_fcheck = fcheck;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
kfree(attrs);
|
||||
kfree(entry);
|
||||
kfree(fcheck);
|
||||
kset_unregister(fcheck_kset);
|
||||
kset_unregister(device_kset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ocfs2_filecheck_remove_sysfs(struct super_block *sb)
|
||||
void ocfs2_filecheck_remove_sysfs(struct ocfs2_super *osb)
|
||||
{
|
||||
return ocfs2_filecheck_sysfs_del(sb->s_id);
|
||||
if (!osb->osb_fc_ent.fs_fcheck)
|
||||
return;
|
||||
|
||||
kobject_del(&osb->osb_fc_ent.fs_kobj);
|
||||
kobject_put(&osb->osb_fc_ent.fs_kobj);
|
||||
wait_for_completion(&osb->osb_fc_ent.fs_kobj_unregister);
|
||||
ocfs2_filecheck_sysfs_free(&osb->osb_fc_ent);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -310,7 +226,7 @@ ocfs2_filecheck_adjust_max(struct ocfs2_filecheck_sysfs_entry *ent,
|
|||
|
||||
spin_lock(&ent->fs_fcheck->fc_lock);
|
||||
if (len < (ent->fs_fcheck->fc_size - ent->fs_fcheck->fc_done)) {
|
||||
mlog(ML_ERROR,
|
||||
mlog(ML_NOTICE,
|
||||
"Cannot set online file check maximum entry number "
|
||||
"to %u due to too many pending entries(%u)\n",
|
||||
len, ent->fs_fcheck->fc_size - ent->fs_fcheck->fc_done);
|
||||
|
|
@ -387,7 +303,7 @@ ocfs2_filecheck_args_parse(const char *name, const char *buf, size_t count,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
|
||||
static ssize_t ocfs2_filecheck_attr_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
|
|
@ -395,19 +311,12 @@ static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
|
|||
ssize_t ret = 0, total = 0, remain = PAGE_SIZE;
|
||||
unsigned int type;
|
||||
struct ocfs2_filecheck_entry *p;
|
||||
struct ocfs2_filecheck_sysfs_entry *ent;
|
||||
struct ocfs2_filecheck_sysfs_entry *ent = container_of(kobj,
|
||||
struct ocfs2_filecheck_sysfs_entry, fs_kobj);
|
||||
|
||||
if (ocfs2_filecheck_type_parse(attr->attr.name, &type))
|
||||
return -EINVAL;
|
||||
|
||||
ent = ocfs2_filecheck_sysfs_get(kobj->parent->name);
|
||||
if (!ent) {
|
||||
mlog(ML_ERROR,
|
||||
"Cannot get the corresponding entry via device basename %s\n",
|
||||
kobj->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (type == OCFS2_FILECHECK_TYPE_SET) {
|
||||
spin_lock(&ent->fs_fcheck->fc_lock);
|
||||
total = snprintf(buf, remain, "%u\n", ent->fs_fcheck->fc_max);
|
||||
|
|
@ -441,11 +350,26 @@ static ssize_t ocfs2_filecheck_show(struct kobject *kobj,
|
|||
spin_unlock(&ent->fs_fcheck->fc_lock);
|
||||
|
||||
exit:
|
||||
ocfs2_filecheck_sysfs_put(ent);
|
||||
return total;
|
||||
}
|
||||
|
||||
static int
|
||||
static inline int
|
||||
ocfs2_filecheck_is_dup_entry(struct ocfs2_filecheck_sysfs_entry *ent,
|
||||
unsigned long ino)
|
||||
{
|
||||
struct ocfs2_filecheck_entry *p;
|
||||
|
||||
list_for_each_entry(p, &ent->fs_fcheck->fc_head, fe_list) {
|
||||
if (!p->fe_done) {
|
||||
if (p->fe_ino == ino)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ocfs2_filecheck_erase_entry(struct ocfs2_filecheck_sysfs_entry *ent)
|
||||
{
|
||||
struct ocfs2_filecheck_entry *p;
|
||||
|
|
@ -484,21 +408,21 @@ static void
|
|||
ocfs2_filecheck_done_entry(struct ocfs2_filecheck_sysfs_entry *ent,
|
||||
struct ocfs2_filecheck_entry *entry)
|
||||
{
|
||||
entry->fe_done = 1;
|
||||
spin_lock(&ent->fs_fcheck->fc_lock);
|
||||
entry->fe_done = 1;
|
||||
ent->fs_fcheck->fc_done++;
|
||||
spin_unlock(&ent->fs_fcheck->fc_lock);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ocfs2_filecheck_handle(struct super_block *sb,
|
||||
ocfs2_filecheck_handle(struct ocfs2_super *osb,
|
||||
unsigned long ino, unsigned int flags)
|
||||
{
|
||||
unsigned int ret = OCFS2_FILECHECK_ERR_SUCCESS;
|
||||
struct inode *inode = NULL;
|
||||
int rc;
|
||||
|
||||
inode = ocfs2_iget(OCFS2_SB(sb), ino, flags, 0);
|
||||
inode = ocfs2_iget(osb, ino, flags, 0);
|
||||
if (IS_ERR(inode)) {
|
||||
rc = (int)(-(long)inode);
|
||||
if (rc >= OCFS2_FILECHECK_ERR_START &&
|
||||
|
|
@ -516,11 +440,14 @@ static void
|
|||
ocfs2_filecheck_handle_entry(struct ocfs2_filecheck_sysfs_entry *ent,
|
||||
struct ocfs2_filecheck_entry *entry)
|
||||
{
|
||||
struct ocfs2_super *osb = container_of(ent, struct ocfs2_super,
|
||||
osb_fc_ent);
|
||||
|
||||
if (entry->fe_type == OCFS2_FILECHECK_TYPE_CHK)
|
||||
entry->fe_status = ocfs2_filecheck_handle(ent->fs_sb,
|
||||
entry->fe_status = ocfs2_filecheck_handle(osb,
|
||||
entry->fe_ino, OCFS2_FI_FLAG_FILECHECK_CHK);
|
||||
else if (entry->fe_type == OCFS2_FILECHECK_TYPE_FIX)
|
||||
entry->fe_status = ocfs2_filecheck_handle(ent->fs_sb,
|
||||
entry->fe_status = ocfs2_filecheck_handle(osb,
|
||||
entry->fe_ino, OCFS2_FI_FLAG_FILECHECK_FIX);
|
||||
else
|
||||
entry->fe_status = OCFS2_FILECHECK_ERR_UNSUPPORTED;
|
||||
|
|
@ -528,30 +455,21 @@ ocfs2_filecheck_handle_entry(struct ocfs2_filecheck_sysfs_entry *ent,
|
|||
ocfs2_filecheck_done_entry(ent, entry);
|
||||
}
|
||||
|
||||
static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
|
||||
static ssize_t ocfs2_filecheck_attr_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
struct ocfs2_filecheck_args args;
|
||||
struct ocfs2_filecheck_entry *entry;
|
||||
struct ocfs2_filecheck_sysfs_entry *ent;
|
||||
ssize_t ret = 0;
|
||||
struct ocfs2_filecheck_sysfs_entry *ent = container_of(kobj,
|
||||
struct ocfs2_filecheck_sysfs_entry, fs_kobj);
|
||||
|
||||
if (count == 0)
|
||||
return count;
|
||||
|
||||
if (ocfs2_filecheck_args_parse(attr->attr.name, buf, count, &args)) {
|
||||
mlog(ML_ERROR, "Invalid arguments for online file check\n");
|
||||
if (ocfs2_filecheck_args_parse(attr->attr.name, buf, count, &args))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ent = ocfs2_filecheck_sysfs_get(kobj->parent->name);
|
||||
if (!ent) {
|
||||
mlog(ML_ERROR,
|
||||
"Cannot get the corresponding entry via device basename %s\n",
|
||||
kobj->parent->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (args.fa_type == OCFS2_FILECHECK_TYPE_SET) {
|
||||
ret = ocfs2_filecheck_adjust_max(ent, args.fa_len);
|
||||
|
|
@ -565,13 +483,16 @@ static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
|
|||
}
|
||||
|
||||
spin_lock(&ent->fs_fcheck->fc_lock);
|
||||
if ((ent->fs_fcheck->fc_size >= ent->fs_fcheck->fc_max) &&
|
||||
(ent->fs_fcheck->fc_done == 0)) {
|
||||
mlog(ML_ERROR,
|
||||
if (ocfs2_filecheck_is_dup_entry(ent, args.fa_ino)) {
|
||||
ret = -EEXIST;
|
||||
kfree(entry);
|
||||
} else if ((ent->fs_fcheck->fc_size >= ent->fs_fcheck->fc_max) &&
|
||||
(ent->fs_fcheck->fc_done == 0)) {
|
||||
mlog(ML_NOTICE,
|
||||
"Cannot do more file check "
|
||||
"since file check queue(%u) is full now\n",
|
||||
ent->fs_fcheck->fc_max);
|
||||
ret = -EBUSY;
|
||||
ret = -EAGAIN;
|
||||
kfree(entry);
|
||||
} else {
|
||||
if ((ent->fs_fcheck->fc_size >= ent->fs_fcheck->fc_max) &&
|
||||
|
|
@ -596,6 +517,5 @@ static ssize_t ocfs2_filecheck_store(struct kobject *kobj,
|
|||
ocfs2_filecheck_handle_entry(ent, entry);
|
||||
|
||||
exit:
|
||||
ocfs2_filecheck_sysfs_put(ent);
|
||||
return (!ret ? count : ret);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,32 @@ enum {
|
|||
#define OCFS2_FILECHECK_ERR_START OCFS2_FILECHECK_ERR_FAILED
|
||||
#define OCFS2_FILECHECK_ERR_END OCFS2_FILECHECK_ERR_UNSUPPORTED
|
||||
|
||||
int ocfs2_filecheck_create_sysfs(struct super_block *sb);
|
||||
int ocfs2_filecheck_remove_sysfs(struct super_block *sb);
|
||||
struct ocfs2_filecheck {
|
||||
struct list_head fc_head; /* File check entry list head */
|
||||
spinlock_t fc_lock;
|
||||
unsigned int fc_max; /* Maximum number of entry in list */
|
||||
unsigned int fc_size; /* Current entry count in list */
|
||||
unsigned int fc_done; /* Finished entry count in list */
|
||||
};
|
||||
|
||||
#define OCFS2_FILECHECK_MAXSIZE 100
|
||||
#define OCFS2_FILECHECK_MINSIZE 10
|
||||
|
||||
/* File check operation type */
|
||||
enum {
|
||||
OCFS2_FILECHECK_TYPE_CHK = 0, /* Check a file(inode) */
|
||||
OCFS2_FILECHECK_TYPE_FIX, /* Fix a file(inode) */
|
||||
OCFS2_FILECHECK_TYPE_SET = 100 /* Set entry list maximum size */
|
||||
};
|
||||
|
||||
struct ocfs2_filecheck_sysfs_entry { /* sysfs entry per partition */
|
||||
struct kobject fs_kobj;
|
||||
struct completion fs_kobj_unregister;
|
||||
struct ocfs2_filecheck *fs_fcheck;
|
||||
};
|
||||
|
||||
|
||||
int ocfs2_filecheck_create_sysfs(struct ocfs2_super *osb);
|
||||
void ocfs2_filecheck_remove_sysfs(struct ocfs2_super *osb);
|
||||
|
||||
#endif /* FILECHECK_H */
|
||||
|
|
|
|||
|
|
@ -1135,7 +1135,7 @@ static void ocfs2_clear_inode(struct inode *inode)
|
|||
trace_ocfs2_clear_inode((unsigned long long)oi->ip_blkno,
|
||||
inode->i_nlink);
|
||||
|
||||
mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,
|
||||
mlog_bug_on_msg(osb == NULL,
|
||||
"Inode=%lu\n", inode->i_ino);
|
||||
|
||||
dquot_drop(inode);
|
||||
|
|
@ -1150,7 +1150,7 @@ static void ocfs2_clear_inode(struct inode *inode)
|
|||
ocfs2_mark_lockres_freeing(osb, &oi->ip_inode_lockres);
|
||||
ocfs2_mark_lockres_freeing(osb, &oi->ip_open_lockres);
|
||||
|
||||
ocfs2_resv_discard(&OCFS2_SB(inode->i_sb)->osb_la_resmap,
|
||||
ocfs2_resv_discard(&osb->osb_la_resmap,
|
||||
&oi->ip_la_data_resv);
|
||||
ocfs2_resv_init_once(&oi->ip_la_data_resv);
|
||||
|
||||
|
|
@ -1160,7 +1160,7 @@ static void ocfs2_clear_inode(struct inode *inode)
|
|||
* exception here are successfully wiped inodes - their
|
||||
* metadata can now be considered to be part of the system
|
||||
* inodes from which it came. */
|
||||
if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED))
|
||||
if (!(oi->ip_flags & OCFS2_INODE_DELETED))
|
||||
ocfs2_checkpoint_inode(inode);
|
||||
|
||||
mlog_bug_on_msg(!list_empty(&oi->ip_io_markers),
|
||||
|
|
@ -1223,7 +1223,7 @@ static void ocfs2_clear_inode(struct inode *inode)
|
|||
* the journal is flushed before journal shutdown. Thus it is safe to
|
||||
* have inodes get cleaned up after journal shutdown.
|
||||
*/
|
||||
jbd2_journal_release_jbd_inode(OCFS2_SB(inode->i_sb)->journal->j_journal,
|
||||
jbd2_journal_release_jbd_inode(osb->journal->j_journal,
|
||||
&oi->ip_jinode);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -525,7 +525,7 @@ static int __ocfs2_mknod_locked(struct inode *dir,
|
|||
* these are used by the support functions here and in
|
||||
* callers. */
|
||||
inode->i_ino = ino_from_blkno(osb->sb, fe_blkno);
|
||||
OCFS2_I(inode)->ip_blkno = fe_blkno;
|
||||
oi->ip_blkno = fe_blkno;
|
||||
spin_lock(&osb->osb_lock);
|
||||
inode->i_generation = osb->s_next_generation++;
|
||||
spin_unlock(&osb->osb_lock);
|
||||
|
|
@ -1186,8 +1186,8 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
|
|||
}
|
||||
|
||||
trace_ocfs2_double_lock_end(
|
||||
(unsigned long long)OCFS2_I(inode1)->ip_blkno,
|
||||
(unsigned long long)OCFS2_I(inode2)->ip_blkno);
|
||||
(unsigned long long)oi1->ip_blkno,
|
||||
(unsigned long long)oi2->ip_blkno);
|
||||
|
||||
bail:
|
||||
if (status)
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#include "reservations.h"
|
||||
|
||||
#include "filecheck.h"
|
||||
|
||||
/* Caching of metadata buffers */
|
||||
|
||||
/* Most user visible OCFS2 inodes will have very few pieces of
|
||||
|
|
@ -472,6 +474,12 @@ struct ocfs2_super
|
|||
* workqueue and schedule on our own.
|
||||
*/
|
||||
struct workqueue_struct *ocfs2_wq;
|
||||
|
||||
/* sysfs directory per partition */
|
||||
struct kset *osb_dev_kset;
|
||||
|
||||
/* file check related stuff */
|
||||
struct ocfs2_filecheck_sysfs_entry osb_fc_ent;
|
||||
};
|
||||
|
||||
#define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info)
|
||||
|
|
|
|||
|
|
@ -1311,11 +1311,11 @@ DEFINE_OCFS2_FILE_OPS(ocfs2_file_release);
|
|||
|
||||
DEFINE_OCFS2_FILE_OPS(ocfs2_sync_file);
|
||||
|
||||
DEFINE_OCFS2_FILE_OPS(ocfs2_file_aio_write);
|
||||
DEFINE_OCFS2_FILE_OPS(ocfs2_file_write_iter);
|
||||
|
||||
DEFINE_OCFS2_FILE_OPS(ocfs2_file_splice_write);
|
||||
|
||||
DEFINE_OCFS2_FILE_OPS(ocfs2_file_aio_read);
|
||||
DEFINE_OCFS2_FILE_OPS(ocfs2_file_read_iter);
|
||||
|
||||
DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_truncate_file);
|
||||
|
||||
|
|
@ -1467,7 +1467,7 @@ TRACE_EVENT(ocfs2_prepare_inode_for_write,
|
|||
__entry->saved_pos, __entry->count, __entry->wait)
|
||||
);
|
||||
|
||||
DEFINE_OCFS2_INT_EVENT(generic_file_aio_read_ret);
|
||||
DEFINE_OCFS2_INT_EVENT(generic_file_read_iter_ret);
|
||||
|
||||
/* End of trace events for fs/ocfs2/file.c. */
|
||||
|
||||
|
|
|
|||
|
|
@ -573,7 +573,7 @@ static int ocfs2_create_refcount_tree(struct inode *inode,
|
|||
BUG_ON(ocfs2_is_refcount_inode(inode));
|
||||
|
||||
trace_ocfs2_create_refcount_tree(
|
||||
(unsigned long long)OCFS2_I(inode)->ip_blkno);
|
||||
(unsigned long long)oi->ip_blkno);
|
||||
|
||||
ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
|
||||
if (ret) {
|
||||
|
|
@ -3359,7 +3359,7 @@ static int ocfs2_replace_cow(struct ocfs2_cow_context *context)
|
|||
unsigned int ext_flags;
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
|
||||
if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) {
|
||||
if (!ocfs2_refcount_tree(osb)) {
|
||||
return ocfs2_error(inode->i_sb, "Inode %lu want to use refcount tree, but the feature bit is not set in the super block\n",
|
||||
inode->i_ino);
|
||||
}
|
||||
|
|
@ -3707,7 +3707,7 @@ int ocfs2_add_refcount_flag(struct inode *inode,
|
|||
trace_ocfs2_add_refcount_flag(ref_blocks, credits);
|
||||
|
||||
if (ref_blocks) {
|
||||
ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(inode->i_sb),
|
||||
ret = ocfs2_reserve_new_metadata_blocks(osb,
|
||||
ref_blocks, &meta_ac);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
|
|
@ -4766,8 +4766,8 @@ static int ocfs2_reflink_inodes_lock(struct inode *s_inode,
|
|||
*bh2 = *bh1;
|
||||
|
||||
trace_ocfs2_double_lock_end(
|
||||
(unsigned long long)OCFS2_I(inode1)->ip_blkno,
|
||||
(unsigned long long)OCFS2_I(inode2)->ip_blkno);
|
||||
(unsigned long long)oi1->ip_blkno,
|
||||
(unsigned long long)oi2->ip_blkno);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,8 +79,6 @@ static u64 ocfs2_group_from_res(struct ocfs2_suballoc_result *res)
|
|||
return ocfs2_which_suballoc_group(res->sr_blkno, res->sr_bit_offset);
|
||||
}
|
||||
|
||||
static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg);
|
||||
static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe);
|
||||
static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl);
|
||||
static int ocfs2_block_group_fill(handle_t *handle,
|
||||
struct inode *alloc_inode,
|
||||
|
|
@ -387,7 +385,7 @@ static int ocfs2_block_group_fill(handle_t *handle,
|
|||
|
||||
memset(bg, 0, sb->s_blocksize);
|
||||
strcpy(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE);
|
||||
bg->bg_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation);
|
||||
bg->bg_generation = cpu_to_le32(osb->fs_generation);
|
||||
bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb, 1,
|
||||
osb->s_feature_incompat));
|
||||
bg->bg_chain = cpu_to_le16(my_chain);
|
||||
|
|
@ -1521,7 +1519,7 @@ static int ocfs2_cluster_group_search(struct inode *inode,
|
|||
OCFS2_I(inode)->ip_clusters, max_bits);
|
||||
}
|
||||
|
||||
ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
|
||||
ret = ocfs2_block_group_find_clear_bits(osb,
|
||||
group_bh, bits_wanted,
|
||||
max_bits, res);
|
||||
if (ret)
|
||||
|
|
@ -2626,53 +2624,6 @@ int ocfs2_release_clusters(handle_t *handle,
|
|||
_ocfs2_clear_bit);
|
||||
}
|
||||
|
||||
static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg)
|
||||
{
|
||||
printk("Block Group:\n");
|
||||
printk("bg_signature: %s\n", bg->bg_signature);
|
||||
printk("bg_size: %u\n", bg->bg_size);
|
||||
printk("bg_bits: %u\n", bg->bg_bits);
|
||||
printk("bg_free_bits_count: %u\n", bg->bg_free_bits_count);
|
||||
printk("bg_chain: %u\n", bg->bg_chain);
|
||||
printk("bg_generation: %u\n", le32_to_cpu(bg->bg_generation));
|
||||
printk("bg_next_group: %llu\n",
|
||||
(unsigned long long)bg->bg_next_group);
|
||||
printk("bg_parent_dinode: %llu\n",
|
||||
(unsigned long long)bg->bg_parent_dinode);
|
||||
printk("bg_blkno: %llu\n",
|
||||
(unsigned long long)bg->bg_blkno);
|
||||
}
|
||||
|
||||
static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe)
|
||||
{
|
||||
int i;
|
||||
|
||||
printk("Suballoc Inode %llu:\n", (unsigned long long)fe->i_blkno);
|
||||
printk("i_signature: %s\n", fe->i_signature);
|
||||
printk("i_size: %llu\n",
|
||||
(unsigned long long)fe->i_size);
|
||||
printk("i_clusters: %u\n", fe->i_clusters);
|
||||
printk("i_generation: %u\n",
|
||||
le32_to_cpu(fe->i_generation));
|
||||
printk("id1.bitmap1.i_used: %u\n",
|
||||
le32_to_cpu(fe->id1.bitmap1.i_used));
|
||||
printk("id1.bitmap1.i_total: %u\n",
|
||||
le32_to_cpu(fe->id1.bitmap1.i_total));
|
||||
printk("id2.i_chain.cl_cpg: %u\n", fe->id2.i_chain.cl_cpg);
|
||||
printk("id2.i_chain.cl_bpc: %u\n", fe->id2.i_chain.cl_bpc);
|
||||
printk("id2.i_chain.cl_count: %u\n", fe->id2.i_chain.cl_count);
|
||||
printk("id2.i_chain.cl_next_free_rec: %u\n",
|
||||
fe->id2.i_chain.cl_next_free_rec);
|
||||
for(i = 0; i < fe->id2.i_chain.cl_next_free_rec; i++) {
|
||||
printk("fe->id2.i_chain.cl_recs[%d].c_free: %u\n", i,
|
||||
fe->id2.i_chain.cl_recs[i].c_free);
|
||||
printk("fe->id2.i_chain.cl_recs[%d].c_total: %u\n", i,
|
||||
fe->id2.i_chain.cl_recs[i].c_total);
|
||||
printk("fe->id2.i_chain.cl_recs[%d].c_blkno: %llu\n", i,
|
||||
(unsigned long long)fe->id2.i_chain.cl_recs[i].c_blkno);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For a given allocation, determine which allocators will need to be
|
||||
* accessed, and lock them, reserving the appropriate number of bits.
|
||||
|
|
|
|||
|
|
@ -423,10 +423,10 @@ static int ocfs2_sync_fs(struct super_block *sb, int wait)
|
|||
ocfs2_schedule_truncate_log_flush(osb, 0);
|
||||
}
|
||||
|
||||
if (jbd2_journal_start_commit(OCFS2_SB(sb)->journal->j_journal,
|
||||
if (jbd2_journal_start_commit(osb->journal->j_journal,
|
||||
&target)) {
|
||||
if (wait)
|
||||
jbd2_log_wait_commit(OCFS2_SB(sb)->journal->j_journal,
|
||||
jbd2_log_wait_commit(osb->journal->j_journal,
|
||||
target);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1161,6 +1161,23 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
|||
|
||||
ocfs2_complete_mount_recovery(osb);
|
||||
|
||||
osb->osb_dev_kset = kset_create_and_add(sb->s_id, NULL,
|
||||
&ocfs2_kset->kobj);
|
||||
if (!osb->osb_dev_kset) {
|
||||
status = -ENOMEM;
|
||||
mlog(ML_ERROR, "Unable to create device kset %s.\n", sb->s_id);
|
||||
goto read_super_error;
|
||||
}
|
||||
|
||||
/* Create filecheck sysfs related directories/files at
|
||||
* /sys/fs/ocfs2/<devname>/filecheck */
|
||||
if (ocfs2_filecheck_create_sysfs(osb)) {
|
||||
status = -ENOMEM;
|
||||
mlog(ML_ERROR, "Unable to create filecheck sysfs directory at "
|
||||
"/sys/fs/ocfs2/%s/filecheck.\n", sb->s_id);
|
||||
goto read_super_error;
|
||||
}
|
||||
|
||||
if (ocfs2_mount_local(osb))
|
||||
snprintf(nodestr, sizeof(nodestr), "local");
|
||||
else
|
||||
|
|
@ -1199,9 +1216,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
|||
/* Start this when the mount is almost sure of being successful */
|
||||
ocfs2_orphan_scan_start(osb);
|
||||
|
||||
/* Create filecheck sysfile /sys/fs/ocfs2/<devname>/filecheck */
|
||||
ocfs2_filecheck_create_sysfs(sb);
|
||||
|
||||
return status;
|
||||
|
||||
read_super_error:
|
||||
|
|
@ -1653,7 +1667,6 @@ static void ocfs2_put_super(struct super_block *sb)
|
|||
|
||||
ocfs2_sync_blockdev(sb);
|
||||
ocfs2_dismount_volume(sb, 0);
|
||||
ocfs2_filecheck_remove_sysfs(sb);
|
||||
}
|
||||
|
||||
static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||||
|
|
@ -1768,12 +1781,9 @@ static int ocfs2_initialize_mem_caches(void)
|
|||
NULL);
|
||||
if (!ocfs2_inode_cachep || !ocfs2_dquot_cachep ||
|
||||
!ocfs2_qf_chunk_cachep) {
|
||||
if (ocfs2_inode_cachep)
|
||||
kmem_cache_destroy(ocfs2_inode_cachep);
|
||||
if (ocfs2_dquot_cachep)
|
||||
kmem_cache_destroy(ocfs2_dquot_cachep);
|
||||
if (ocfs2_qf_chunk_cachep)
|
||||
kmem_cache_destroy(ocfs2_qf_chunk_cachep);
|
||||
kmem_cache_destroy(ocfs2_inode_cachep);
|
||||
kmem_cache_destroy(ocfs2_dquot_cachep);
|
||||
kmem_cache_destroy(ocfs2_qf_chunk_cachep);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
@ -1787,16 +1797,13 @@ static void ocfs2_free_mem_caches(void)
|
|||
* destroy cache.
|
||||
*/
|
||||
rcu_barrier();
|
||||
if (ocfs2_inode_cachep)
|
||||
kmem_cache_destroy(ocfs2_inode_cachep);
|
||||
kmem_cache_destroy(ocfs2_inode_cachep);
|
||||
ocfs2_inode_cachep = NULL;
|
||||
|
||||
if (ocfs2_dquot_cachep)
|
||||
kmem_cache_destroy(ocfs2_dquot_cachep);
|
||||
kmem_cache_destroy(ocfs2_dquot_cachep);
|
||||
ocfs2_dquot_cachep = NULL;
|
||||
|
||||
if (ocfs2_qf_chunk_cachep)
|
||||
kmem_cache_destroy(ocfs2_qf_chunk_cachep);
|
||||
kmem_cache_destroy(ocfs2_qf_chunk_cachep);
|
||||
ocfs2_qf_chunk_cachep = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1899,6 +1906,12 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
|
|||
osb = OCFS2_SB(sb);
|
||||
BUG_ON(!osb);
|
||||
|
||||
/* Remove file check sysfs related directores/files,
|
||||
* and wait for the pending file check operations */
|
||||
ocfs2_filecheck_remove_sysfs(osb);
|
||||
|
||||
kset_unregister(osb->osb_dev_kset);
|
||||
|
||||
debugfs_remove(osb->osb_ctxt);
|
||||
|
||||
/* Orphan scan should be stopped as early as possible */
|
||||
|
|
|
|||
|
|
@ -633,6 +633,5 @@ int __init init_ocfs2_uptodate_cache(void)
|
|||
|
||||
void exit_ocfs2_uptodate_cache(void)
|
||||
{
|
||||
if (ocfs2_uptodate_cachep)
|
||||
kmem_cache_destroy(ocfs2_uptodate_cachep);
|
||||
kmem_cache_destroy(ocfs2_uptodate_cachep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3564,7 +3564,7 @@ int ocfs2_xattr_set(struct inode *inode,
|
|||
.not_found = -ENODATA,
|
||||
};
|
||||
|
||||
if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb)))
|
||||
if (!ocfs2_supports_xattr(osb))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue