You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2: (27 commits) ocfs2: Cache extent records ocfs2: Remember rw lock level during direct io ocfs2: Fix up i_blocks calculation to know about holes ocfs2: Fix extent lookup to return true size of holes ocfs2: Read from an unwritten extent returns zeros ocfs2: make room for unwritten extents flag ocfs2: Use own splice write actor ocfs2: Use do_sync_mapping_range() in ocfs2_zero_tail_for_truncate() [PATCH] Turn do_sync_file_range() into do_sync_mapping_range() ocfs2: zero tail of sparse files on truncate ocfs2: Teach ocfs2_get_block() about holes ocfs2: remove ocfs2_prepare_write() and ocfs2_commit_write() ocfs2: teach ocfs2_file_aio_write() about sparse files ocfs2: Turn off shared writeable mmap for local files systems with holes. ocfs2: abstract out allocation locking ocfs2: teach extend/truncate about sparse files ocfs2: temporarily remove extent map caching ocfs2: sparse b-tree support ocfs2: small cleanup of ocfs2_request_delete() ocfs2: remove unused code ...
This commit is contained in:
+2467
-614
File diff suppressed because it is too large
Load Diff
+26
-1
@@ -31,7 +31,8 @@ int ocfs2_insert_extent(struct ocfs2_super *osb,
|
||||
handle_t *handle,
|
||||
struct inode *inode,
|
||||
struct buffer_head *fe_bh,
|
||||
u64 blkno,
|
||||
u32 cpos,
|
||||
u64 start_blk,
|
||||
u32 new_clusters,
|
||||
struct ocfs2_alloc_context *meta_ac);
|
||||
int ocfs2_num_free_extents(struct ocfs2_super *osb,
|
||||
@@ -70,6 +71,8 @@ struct ocfs2_truncate_context {
|
||||
struct buffer_head *tc_last_eb_bh;
|
||||
};
|
||||
|
||||
int ocfs2_zero_tail_for_truncate(struct inode *inode, handle_t *handle,
|
||||
u64 new_i_size);
|
||||
int ocfs2_prepare_truncate(struct ocfs2_super *osb,
|
||||
struct inode *inode,
|
||||
struct buffer_head *fe_bh,
|
||||
@@ -79,4 +82,26 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
|
||||
struct buffer_head *fe_bh,
|
||||
struct ocfs2_truncate_context *tc);
|
||||
|
||||
int ocfs2_find_leaf(struct inode *inode, struct ocfs2_extent_list *root_el,
|
||||
u32 cpos, struct buffer_head **leaf_bh);
|
||||
|
||||
/*
|
||||
* Helper function to look at the # of clusters in an extent record.
|
||||
*/
|
||||
static inline unsigned int ocfs2_rec_clusters(struct ocfs2_extent_list *el,
|
||||
struct ocfs2_extent_rec *rec)
|
||||
{
|
||||
/*
|
||||
* Cluster count in extent records is slightly different
|
||||
* between interior nodes and leaf nodes. This is to support
|
||||
* unwritten extents which need a flags field in leaf node
|
||||
* records, thus shrinking the available space for a clusters
|
||||
* field.
|
||||
*/
|
||||
if (el->l_tree_depth)
|
||||
return le32_to_cpu(rec->e_int_clusters);
|
||||
else
|
||||
return le16_to_cpu(rec->e_leaf_clusters);
|
||||
}
|
||||
|
||||
#endif /* OCFS2_ALLOC_H */
|
||||
|
||||
+820
-191
File diff suppressed because it is too large
Load Diff
+74
-3
@@ -30,12 +30,83 @@ handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
|
||||
unsigned from,
|
||||
unsigned to);
|
||||
|
||||
int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
|
||||
struct inode *inode, unsigned int from,
|
||||
unsigned int to, int new);
|
||||
|
||||
int walk_page_buffers( handle_t *handle,
|
||||
struct buffer_head *head,
|
||||
unsigned from,
|
||||
unsigned to,
|
||||
int *partial,
|
||||
int (*fn)( handle_t *handle,
|
||||
struct buffer_head *bh));
|
||||
|
||||
struct ocfs2_write_ctxt;
|
||||
typedef int (ocfs2_page_writer)(struct inode *, struct ocfs2_write_ctxt *,
|
||||
u64 *, unsigned int *, unsigned int *);
|
||||
|
||||
ssize_t ocfs2_buffered_write_cluster(struct file *file, loff_t pos,
|
||||
size_t count, ocfs2_page_writer *actor,
|
||||
void *priv);
|
||||
|
||||
struct ocfs2_write_ctxt {
|
||||
size_t w_count;
|
||||
loff_t w_pos;
|
||||
u32 w_cpos;
|
||||
unsigned int w_finished_copy;
|
||||
|
||||
/* This is true if page_size > cluster_size */
|
||||
unsigned int w_large_pages;
|
||||
|
||||
/* Filler callback and private data */
|
||||
ocfs2_page_writer *w_write_data_page;
|
||||
void *w_private;
|
||||
|
||||
/* Only valid for the filler callback */
|
||||
struct page *w_this_page;
|
||||
unsigned int w_this_page_new;
|
||||
};
|
||||
|
||||
struct ocfs2_buffered_write_priv {
|
||||
char *b_src_buf;
|
||||
const struct iovec *b_cur_iov; /* Current iovec */
|
||||
size_t b_cur_off; /* Offset in the
|
||||
* current iovec */
|
||||
};
|
||||
int ocfs2_map_and_write_user_data(struct inode *inode,
|
||||
struct ocfs2_write_ctxt *wc,
|
||||
u64 *p_blkno,
|
||||
unsigned int *ret_from,
|
||||
unsigned int *ret_to);
|
||||
|
||||
struct ocfs2_splice_write_priv {
|
||||
struct splice_desc *s_sd;
|
||||
struct pipe_buffer *s_buf;
|
||||
struct pipe_inode_info *s_pipe;
|
||||
/* Neither offset value is ever larger than one page */
|
||||
unsigned int s_offset;
|
||||
unsigned int s_buf_offset;
|
||||
};
|
||||
int ocfs2_map_and_write_splice_data(struct inode *inode,
|
||||
struct ocfs2_write_ctxt *wc,
|
||||
u64 *p_blkno,
|
||||
unsigned int *ret_from,
|
||||
unsigned int *ret_to);
|
||||
|
||||
/* all ocfs2_dio_end_io()'s fault */
|
||||
#define ocfs2_iocb_is_rw_locked(iocb) \
|
||||
test_bit(0, (unsigned long *)&iocb->private)
|
||||
#define ocfs2_iocb_set_rw_locked(iocb) \
|
||||
set_bit(0, (unsigned long *)&iocb->private)
|
||||
static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level)
|
||||
{
|
||||
set_bit(0, (unsigned long *)&iocb->private);
|
||||
if (level)
|
||||
set_bit(1, (unsigned long *)&iocb->private);
|
||||
else
|
||||
clear_bit(1, (unsigned long *)&iocb->private);
|
||||
}
|
||||
#define ocfs2_iocb_clear_rw_locked(iocb) \
|
||||
clear_bit(0, (unsigned long *)&iocb->private)
|
||||
|
||||
#define ocfs2_iocb_rw_locked_level(iocb) \
|
||||
test_bit(1, (unsigned long *)&iocb->private)
|
||||
#endif /* OCFS2_FILE_H */
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include "heartbeat.h"
|
||||
#include "nodemanager.h"
|
||||
@@ -72,7 +73,9 @@ static void o2quo_fence_self(void)
|
||||
/* panic spins with interrupts enabled. with preempt
|
||||
* threads can still schedule, etc, etc */
|
||||
o2hb_stop_all_regions();
|
||||
panic("ocfs2 is very sorry to be fencing this system by panicing\n");
|
||||
|
||||
printk("ocfs2 is very sorry to be fencing this system by restarting\n");
|
||||
emergency_restart();
|
||||
}
|
||||
|
||||
/* Indicate that a timeout occured on a hearbeat region write. The
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
* locking semantics of the file system using the protocol. It should
|
||||
* be somewhere else, I'm sure, but right now it isn't.
|
||||
*
|
||||
* New in version 8:
|
||||
* - Replace delete inode votes with a cluster lock
|
||||
*
|
||||
* New in version 7:
|
||||
* - DLM join domain includes the live nodemap
|
||||
*
|
||||
@@ -57,7 +60,7 @@
|
||||
* - full 64 bit i_size in the metadata lock lvbs
|
||||
* - introduction of "rw" lock and pushing meta/data locking down
|
||||
*/
|
||||
#define O2NET_PROTOCOL_VERSION 7ULL
|
||||
#define O2NET_PROTOCOL_VERSION 8ULL
|
||||
struct o2net_handshake {
|
||||
__be64 protocol_version;
|
||||
__be64 connector_id;
|
||||
|
||||
+8
-7
@@ -358,15 +358,17 @@ int ocfs2_do_extend_dir(struct super_block *sb,
|
||||
{
|
||||
int status;
|
||||
int extend;
|
||||
u64 p_blkno;
|
||||
u64 p_blkno, v_blkno;
|
||||
|
||||
spin_lock(&OCFS2_I(dir)->ip_lock);
|
||||
extend = (i_size_read(dir) == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters));
|
||||
spin_unlock(&OCFS2_I(dir)->ip_lock);
|
||||
|
||||
if (extend) {
|
||||
status = ocfs2_do_extend_allocation(OCFS2_SB(sb), dir, 1,
|
||||
parent_fe_bh, handle,
|
||||
u32 offset = OCFS2_I(dir)->ip_clusters;
|
||||
|
||||
status = ocfs2_do_extend_allocation(OCFS2_SB(sb), dir, &offset,
|
||||
1, parent_fe_bh, handle,
|
||||
data_ac, meta_ac, NULL);
|
||||
BUG_ON(status == -EAGAIN);
|
||||
if (status < 0) {
|
||||
@@ -375,9 +377,8 @@ int ocfs2_do_extend_dir(struct super_block *sb,
|
||||
}
|
||||
}
|
||||
|
||||
status = ocfs2_extent_map_get_blocks(dir, (dir->i_blocks >>
|
||||
(sb->s_blocksize_bits - 9)),
|
||||
1, &p_blkno, NULL);
|
||||
v_blkno = ocfs2_blocks_for_bytes(sb, i_size_read(dir));
|
||||
status = ocfs2_extent_map_get_blocks(dir, v_blkno, &p_blkno, NULL, NULL);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
@@ -486,7 +487,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
|
||||
|
||||
dir_i_size += dir->i_sb->s_blocksize;
|
||||
i_size_write(dir, dir_i_size);
|
||||
dir->i_blocks = ocfs2_align_bytes_to_sectors(dir_i_size);
|
||||
dir->i_blocks = ocfs2_inode_sector_count(dir);
|
||||
status = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
|
||||
@@ -430,11 +430,10 @@ redo_bucket:
|
||||
|
||||
dlm_lockres_put(res);
|
||||
|
||||
cond_resched_lock(&dlm->spinlock);
|
||||
|
||||
if (dropped)
|
||||
goto redo_bucket;
|
||||
}
|
||||
cond_resched_lock(&dlm->spinlock);
|
||||
num += n;
|
||||
mlog(0, "%s: touched %d lockreses in bucket %d "
|
||||
"(tot=%d)\n", dlm->name, n, i, num);
|
||||
@@ -1035,7 +1034,7 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm)
|
||||
{
|
||||
int status = 0, tmpstat, node;
|
||||
struct domain_join_ctxt *ctxt;
|
||||
enum dlm_query_join_response response;
|
||||
enum dlm_query_join_response response = JOIN_DISALLOW;
|
||||
|
||||
mlog_entry("%p", dlm);
|
||||
|
||||
|
||||
@@ -611,6 +611,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
|
||||
}
|
||||
} while (status != 0);
|
||||
|
||||
spin_lock(&dlm_reco_state_lock);
|
||||
switch (ndata->state) {
|
||||
case DLM_RECO_NODE_DATA_INIT:
|
||||
case DLM_RECO_NODE_DATA_FINALIZE_SENT:
|
||||
@@ -641,6 +642,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
|
||||
ndata->node_num, dead_node);
|
||||
break;
|
||||
}
|
||||
spin_unlock(&dlm_reco_state_lock);
|
||||
}
|
||||
|
||||
mlog(0, "done requesting all lock info\n");
|
||||
|
||||
+126
-17
@@ -225,11 +225,17 @@ static struct ocfs2_lock_res_ops ocfs2_dentry_lops = {
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
static struct ocfs2_lock_res_ops ocfs2_inode_open_lops = {
|
||||
.get_osb = ocfs2_get_inode_osb,
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres)
|
||||
{
|
||||
return lockres->l_type == OCFS2_LOCK_TYPE_META ||
|
||||
lockres->l_type == OCFS2_LOCK_TYPE_DATA ||
|
||||
lockres->l_type == OCFS2_LOCK_TYPE_RW;
|
||||
lockres->l_type == OCFS2_LOCK_TYPE_RW ||
|
||||
lockres->l_type == OCFS2_LOCK_TYPE_OPEN;
|
||||
}
|
||||
|
||||
static inline struct inode *ocfs2_lock_res_inode(struct ocfs2_lock_res *lockres)
|
||||
@@ -373,6 +379,9 @@ void ocfs2_inode_lock_res_init(struct ocfs2_lock_res *res,
|
||||
case OCFS2_LOCK_TYPE_DATA:
|
||||
ops = &ocfs2_inode_data_lops;
|
||||
break;
|
||||
case OCFS2_LOCK_TYPE_OPEN:
|
||||
ops = &ocfs2_inode_open_lops;
|
||||
break;
|
||||
default:
|
||||
mlog_bug_on_msg(1, "type: %d\n", type);
|
||||
ops = NULL; /* thanks, gcc */
|
||||
@@ -1129,6 +1138,12 @@ int ocfs2_create_new_inode_locks(struct inode *inode)
|
||||
goto bail;
|
||||
}
|
||||
|
||||
ret = ocfs2_create_new_lock(osb, &OCFS2_I(inode)->ip_open_lockres, 0, 0);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
mlog_exit(ret);
|
||||
return ret;
|
||||
@@ -1182,6 +1197,99 @@ void ocfs2_rw_unlock(struct inode *inode, int write)
|
||||
mlog_exit_void();
|
||||
}
|
||||
|
||||
/*
|
||||
* ocfs2_open_lock always get PR mode lock.
|
||||
*/
|
||||
int ocfs2_open_lock(struct inode *inode)
|
||||
{
|
||||
int status = 0;
|
||||
struct ocfs2_lock_res *lockres;
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
|
||||
BUG_ON(!inode);
|
||||
|
||||
mlog_entry_void();
|
||||
|
||||
mlog(0, "inode %llu take PRMODE open lock\n",
|
||||
(unsigned long long)OCFS2_I(inode)->ip_blkno);
|
||||
|
||||
if (ocfs2_mount_local(osb))
|
||||
goto out;
|
||||
|
||||
lockres = &OCFS2_I(inode)->ip_open_lockres;
|
||||
|
||||
status = ocfs2_cluster_lock(OCFS2_SB(inode->i_sb), lockres,
|
||||
LKM_PRMODE, 0, 0);
|
||||
if (status < 0)
|
||||
mlog_errno(status);
|
||||
|
||||
out:
|
||||
mlog_exit(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
int ocfs2_try_open_lock(struct inode *inode, int write)
|
||||
{
|
||||
int status = 0, level;
|
||||
struct ocfs2_lock_res *lockres;
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
|
||||
BUG_ON(!inode);
|
||||
|
||||
mlog_entry_void();
|
||||
|
||||
mlog(0, "inode %llu try to take %s open lock\n",
|
||||
(unsigned long long)OCFS2_I(inode)->ip_blkno,
|
||||
write ? "EXMODE" : "PRMODE");
|
||||
|
||||
if (ocfs2_mount_local(osb))
|
||||
goto out;
|
||||
|
||||
lockres = &OCFS2_I(inode)->ip_open_lockres;
|
||||
|
||||
level = write ? LKM_EXMODE : LKM_PRMODE;
|
||||
|
||||
/*
|
||||
* The file system may already holding a PRMODE/EXMODE open lock.
|
||||
* Since we pass LKM_NOQUEUE, the request won't block waiting on
|
||||
* 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, LKM_NOQUEUE, 0);
|
||||
|
||||
out:
|
||||
mlog_exit(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* ocfs2_open_unlock unlock PR and EX mode open locks.
|
||||
*/
|
||||
void ocfs2_open_unlock(struct inode *inode)
|
||||
{
|
||||
struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_open_lockres;
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
|
||||
mlog_entry_void();
|
||||
|
||||
mlog(0, "inode %llu drop open lock\n",
|
||||
(unsigned long long)OCFS2_I(inode)->ip_blkno);
|
||||
|
||||
if (ocfs2_mount_local(osb))
|
||||
goto out;
|
||||
|
||||
if(lockres->l_ro_holders)
|
||||
ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres,
|
||||
LKM_PRMODE);
|
||||
if(lockres->l_ex_holders)
|
||||
ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres,
|
||||
LKM_EXMODE);
|
||||
|
||||
out:
|
||||
mlog_exit_void();
|
||||
}
|
||||
|
||||
int ocfs2_data_lock_full(struct inode *inode,
|
||||
int write,
|
||||
int arg_flags)
|
||||
@@ -1387,8 +1495,7 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
|
||||
if (S_ISLNK(inode->i_mode) && !oi->ip_clusters)
|
||||
inode->i_blocks = 0;
|
||||
else
|
||||
inode->i_blocks =
|
||||
ocfs2_align_bytes_to_sectors(i_size_read(inode));
|
||||
inode->i_blocks = ocfs2_inode_sector_count(inode);
|
||||
|
||||
inode->i_uid = be32_to_cpu(lvb->lvb_iuid);
|
||||
inode->i_gid = be32_to_cpu(lvb->lvb_igid);
|
||||
@@ -1479,12 +1586,15 @@ static int ocfs2_meta_lock_update(struct inode *inode,
|
||||
{
|
||||
int status = 0;
|
||||
struct ocfs2_inode_info *oi = OCFS2_I(inode);
|
||||
struct ocfs2_lock_res *lockres = NULL;
|
||||
struct ocfs2_lock_res *lockres = &oi->ip_meta_lockres;
|
||||
struct ocfs2_dinode *fe;
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
|
||||
mlog_entry_void();
|
||||
|
||||
if (ocfs2_mount_local(osb))
|
||||
goto bail;
|
||||
|
||||
spin_lock(&oi->ip_lock);
|
||||
if (oi->ip_flags & OCFS2_INODE_DELETED) {
|
||||
mlog(0, "Orphaned inode %llu was deleted while we "
|
||||
@@ -1496,22 +1606,16 @@ static int ocfs2_meta_lock_update(struct inode *inode,
|
||||
}
|
||||
spin_unlock(&oi->ip_lock);
|
||||
|
||||
if (!ocfs2_mount_local(osb)) {
|
||||
lockres = &oi->ip_meta_lockres;
|
||||
|
||||
if (!ocfs2_should_refresh_lock_res(lockres))
|
||||
goto bail;
|
||||
}
|
||||
if (!ocfs2_should_refresh_lock_res(lockres))
|
||||
goto bail;
|
||||
|
||||
/* This will discard any caching information we might have had
|
||||
* for the inode metadata. */
|
||||
ocfs2_metadata_cache_purge(inode);
|
||||
|
||||
/* will do nothing for inode types that don't use the extent
|
||||
* map (directories, bitmap files, etc) */
|
||||
ocfs2_extent_map_trunc(inode, 0);
|
||||
|
||||
if (lockres && ocfs2_meta_lvb_is_trustable(inode, lockres)) {
|
||||
if (ocfs2_meta_lvb_is_trustable(inode, lockres)) {
|
||||
mlog(0, "Trusting LVB on inode %llu\n",
|
||||
(unsigned long long)oi->ip_blkno);
|
||||
ocfs2_refresh_inode_from_lvb(inode);
|
||||
@@ -1558,8 +1662,7 @@ static int ocfs2_meta_lock_update(struct inode *inode,
|
||||
|
||||
status = 0;
|
||||
bail_refresh:
|
||||
if (lockres)
|
||||
ocfs2_complete_lock_res_refresh(lockres, status);
|
||||
ocfs2_complete_lock_res_refresh(lockres, status);
|
||||
bail:
|
||||
mlog_exit(status);
|
||||
return status;
|
||||
@@ -1630,7 +1733,6 @@ int ocfs2_meta_lock_full(struct inode *inode,
|
||||
wait_event(osb->recovery_event,
|
||||
ocfs2_node_map_is_empty(osb, &osb->recovery_map));
|
||||
|
||||
acquired = 0;
|
||||
lockres = &OCFS2_I(inode)->ip_meta_lockres;
|
||||
level = ex ? LKM_EXMODE : LKM_PRMODE;
|
||||
dlm_flags = 0;
|
||||
@@ -2458,12 +2560,19 @@ int ocfs2_drop_inode_locks(struct inode *inode)
|
||||
* ocfs2_clear_inode has done it for us. */
|
||||
|
||||
err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
|
||||
&OCFS2_I(inode)->ip_data_lockres);
|
||||
&OCFS2_I(inode)->ip_open_lockres);
|
||||
if (err < 0)
|
||||
mlog_errno(err);
|
||||
|
||||
status = err;
|
||||
|
||||
err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
|
||||
&OCFS2_I(inode)->ip_data_lockres);
|
||||
if (err < 0)
|
||||
mlog_errno(err);
|
||||
if (err < 0 && !status)
|
||||
status = err;
|
||||
|
||||
err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
|
||||
&OCFS2_I(inode)->ip_meta_lockres);
|
||||
if (err < 0)
|
||||
|
||||
@@ -80,6 +80,9 @@ void ocfs2_data_unlock(struct inode *inode,
|
||||
int write);
|
||||
int ocfs2_rw_lock(struct inode *inode, int write);
|
||||
void ocfs2_rw_unlock(struct inode *inode, int write);
|
||||
int ocfs2_open_lock(struct inode *inode);
|
||||
int ocfs2_try_open_lock(struct inode *inode, int write);
|
||||
void ocfs2_open_unlock(struct inode *inode);
|
||||
int ocfs2_meta_lock_atime(struct inode *inode,
|
||||
struct vfsmount *vfsmnt,
|
||||
int *level);
|
||||
|
||||
+439
-928
File diff suppressed because it is too large
Load Diff
+23
-16
@@ -25,22 +25,29 @@
|
||||
#ifndef _EXTENT_MAP_H
|
||||
#define _EXTENT_MAP_H
|
||||
|
||||
int init_ocfs2_extent_maps(void);
|
||||
void exit_ocfs2_extent_maps(void);
|
||||
struct ocfs2_extent_map_item {
|
||||
unsigned int ei_cpos;
|
||||
unsigned int ei_phys;
|
||||
unsigned int ei_clusters;
|
||||
unsigned int ei_flags;
|
||||
|
||||
/*
|
||||
* EVERY CALL here except _init, _trunc, and _drop expects alloc_sem
|
||||
* to be held. The allocation cannot change at all while the map is
|
||||
* in the process of being updated.
|
||||
*/
|
||||
int ocfs2_extent_map_init(struct inode *inode);
|
||||
int ocfs2_extent_map_append(struct inode *inode,
|
||||
struct ocfs2_extent_rec *rec,
|
||||
u32 new_clusters);
|
||||
int ocfs2_extent_map_get_blocks(struct inode *inode,
|
||||
u64 v_blkno, int count,
|
||||
u64 *p_blkno, int *ret_count);
|
||||
int ocfs2_extent_map_drop(struct inode *inode, u32 new_clusters);
|
||||
int ocfs2_extent_map_trunc(struct inode *inode, u32 new_clusters);
|
||||
struct list_head ei_list;
|
||||
};
|
||||
|
||||
#define OCFS2_MAX_EXTENT_MAP_ITEMS 3
|
||||
struct ocfs2_extent_map {
|
||||
unsigned int em_num_items;
|
||||
struct list_head em_list;
|
||||
};
|
||||
|
||||
void ocfs2_extent_map_init(struct inode *inode);
|
||||
void ocfs2_extent_map_trunc(struct inode *inode, unsigned int cluster);
|
||||
void ocfs2_extent_map_insert_rec(struct inode *inode,
|
||||
struct ocfs2_extent_rec *rec);
|
||||
|
||||
int ocfs2_get_clusters(struct inode *inode, u32 v_cluster, u32 *p_cluster,
|
||||
u32 *num_clusters, unsigned int *extent_flags);
|
||||
int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
|
||||
u64 *ret_count, unsigned int *extent_flags);
|
||||
|
||||
#endif /* _EXTENT_MAP_H */
|
||||
|
||||
+549
-84
File diff suppressed because it is too large
Load Diff
@@ -39,12 +39,17 @@ enum ocfs2_alloc_restarted {
|
||||
};
|
||||
int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
|
||||
struct inode *inode,
|
||||
u32 *cluster_start,
|
||||
u32 clusters_to_add,
|
||||
struct buffer_head *fe_bh,
|
||||
handle_t *handle,
|
||||
struct ocfs2_alloc_context *data_ac,
|
||||
struct ocfs2_alloc_context *meta_ac,
|
||||
enum ocfs2_alloc_restarted *reason);
|
||||
int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di,
|
||||
u32 clusters_to_add,
|
||||
struct ocfs2_alloc_context **data_ac,
|
||||
struct ocfs2_alloc_context **meta_ac);
|
||||
int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
|
||||
int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||
struct kstat *stat);
|
||||
|
||||
+94
-109
@@ -89,24 +89,6 @@ void ocfs2_set_inode_flags(struct inode *inode)
|
||||
inode->i_flags |= S_DIRSYNC;
|
||||
}
|
||||
|
||||
struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
|
||||
u64 blkno,
|
||||
int delete_vote)
|
||||
{
|
||||
struct ocfs2_find_inode_args args;
|
||||
|
||||
/* ocfs2_ilookup_for_vote should *only* be called from the
|
||||
* vote thread */
|
||||
BUG_ON(current != osb->vote_task);
|
||||
|
||||
args.fi_blkno = blkno;
|
||||
args.fi_flags = OCFS2_FI_FLAG_NOWAIT;
|
||||
if (delete_vote)
|
||||
args.fi_flags |= OCFS2_FI_FLAG_DELETE;
|
||||
args.fi_ino = ino_from_blkno(osb->sb, blkno);
|
||||
return ilookup5(osb->sb, args.fi_ino, ocfs2_find_actor, &args);
|
||||
}
|
||||
|
||||
struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, int flags)
|
||||
{
|
||||
struct inode *inode = NULL;
|
||||
@@ -182,28 +164,6 @@ static int ocfs2_find_actor(struct inode *inode, void *opaque)
|
||||
if (oi->ip_blkno != args->fi_blkno)
|
||||
goto bail;
|
||||
|
||||
/* OCFS2_FI_FLAG_NOWAIT is *only* set from
|
||||
* ocfs2_ilookup_for_vote which won't create an inode for one
|
||||
* that isn't found. The vote thread which doesn't want to get
|
||||
* an inode which is in the process of going away - otherwise
|
||||
* the call to __wait_on_freeing_inode in find_inode_fast will
|
||||
* cause it to deadlock on an inode which may be waiting on a
|
||||
* vote (or lock release) in delete_inode */
|
||||
if ((args->fi_flags & OCFS2_FI_FLAG_NOWAIT) &&
|
||||
(inode->i_state & (I_FREEING|I_CLEAR))) {
|
||||
/* As stated above, we're not going to return an
|
||||
* inode. In the case of a delete vote, the voting
|
||||
* code is going to signal the other node to go
|
||||
* ahead. Mark that state here, so this freeing inode
|
||||
* has the state when it gets to delete_inode. */
|
||||
if (args->fi_flags & OCFS2_FI_FLAG_DELETE) {
|
||||
spin_lock(&oi->ip_lock);
|
||||
ocfs2_mark_inode_remotely_deleted(inode);
|
||||
spin_unlock(&oi->ip_lock);
|
||||
}
|
||||
goto bail;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
bail:
|
||||
mlog_exit(ret);
|
||||
@@ -261,6 +221,9 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
|
||||
goto bail;
|
||||
}
|
||||
|
||||
OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
|
||||
OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
|
||||
|
||||
inode->i_version = 1;
|
||||
inode->i_generation = le32_to_cpu(fe->i_generation);
|
||||
inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
|
||||
@@ -272,8 +235,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
|
||||
if (S_ISLNK(inode->i_mode) && !fe->i_clusters)
|
||||
inode->i_blocks = 0;
|
||||
else
|
||||
inode->i_blocks =
|
||||
ocfs2_align_bytes_to_sectors(le64_to_cpu(fe->i_size));
|
||||
inode->i_blocks = ocfs2_inode_sector_count(inode);
|
||||
inode->i_mapping->a_ops = &ocfs2_aops;
|
||||
inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
|
||||
inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
|
||||
@@ -288,10 +250,6 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
|
||||
(unsigned long long)OCFS2_I(inode)->ip_blkno,
|
||||
(unsigned long long)fe->i_blkno);
|
||||
|
||||
OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
|
||||
OCFS2_I(inode)->ip_orphaned_slot = OCFS2_INVALID_SLOT;
|
||||
OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
|
||||
|
||||
inode->i_nlink = le16_to_cpu(fe->i_links_count);
|
||||
|
||||
if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL))
|
||||
@@ -347,6 +305,9 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
|
||||
|
||||
ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_meta_lockres,
|
||||
OCFS2_LOCK_TYPE_META, 0, inode);
|
||||
|
||||
ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_open_lockres,
|
||||
OCFS2_LOCK_TYPE_OPEN, 0, inode);
|
||||
}
|
||||
|
||||
ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_rw_lockres,
|
||||
@@ -421,7 +382,7 @@ static int ocfs2_read_locked_inode(struct inode *inode,
|
||||
* cluster lock before trusting anything anyway.
|
||||
*/
|
||||
can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE)
|
||||
&& !(args->fi_flags & OCFS2_FI_FLAG_NOLOCK)
|
||||
&& !(args->fi_flags & OCFS2_FI_FLAG_ORPHAN_RECOVERY)
|
||||
&& !ocfs2_mount_local(osb);
|
||||
|
||||
/*
|
||||
@@ -438,7 +399,17 @@ static int ocfs2_read_locked_inode(struct inode *inode,
|
||||
OCFS2_LOCK_TYPE_META,
|
||||
generation, inode);
|
||||
|
||||
ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_open_lockres,
|
||||
OCFS2_LOCK_TYPE_OPEN,
|
||||
0, inode);
|
||||
|
||||
if (can_lock) {
|
||||
status = ocfs2_open_lock(inode);
|
||||
if (status) {
|
||||
make_bad_inode(inode);
|
||||
mlog_errno(status);
|
||||
return status;
|
||||
}
|
||||
status = ocfs2_meta_lock(inode, NULL, 0);
|
||||
if (status) {
|
||||
make_bad_inode(inode);
|
||||
@@ -447,6 +418,14 @@ static int ocfs2_read_locked_inode(struct inode *inode,
|
||||
}
|
||||
}
|
||||
|
||||
if (args->fi_flags & OCFS2_FI_FLAG_ORPHAN_RECOVERY) {
|
||||
status = ocfs2_try_open_lock(inode, 0);
|
||||
if (status) {
|
||||
make_bad_inode(inode);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0,
|
||||
can_lock ? inode : NULL);
|
||||
if (status < 0) {
|
||||
@@ -507,50 +486,56 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
|
||||
struct buffer_head *fe_bh)
|
||||
{
|
||||
int status = 0;
|
||||
handle_t *handle = NULL;
|
||||
struct ocfs2_truncate_context *tc = NULL;
|
||||
struct ocfs2_dinode *fe;
|
||||
handle_t *handle = NULL;
|
||||
|
||||
mlog_entry_void();
|
||||
|
||||
fe = (struct ocfs2_dinode *) fe_bh->b_data;
|
||||
|
||||
/* zero allocation, zero truncate :) */
|
||||
if (!fe->i_clusters)
|
||||
goto bail;
|
||||
if (fe->i_clusters) {
|
||||
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
|
||||
if (IS_ERR(handle)) {
|
||||
status = PTR_ERR(handle);
|
||||
mlog_errno(status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
|
||||
if (IS_ERR(handle)) {
|
||||
status = PTR_ERR(handle);
|
||||
status = ocfs2_journal_access(handle, inode, fe_bh,
|
||||
OCFS2_JOURNAL_ACCESS_WRITE);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
i_size_write(inode, 0);
|
||||
|
||||
status = ocfs2_mark_inode_dirty(handle, inode, fe_bh);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ocfs2_commit_trans(osb, handle);
|
||||
handle = NULL;
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
|
||||
status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
status = ocfs2_commit_truncate(osb, inode, fe_bh, tc);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
status = ocfs2_set_inode_size(handle, inode, fe_bh, 0ULL);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
ocfs2_commit_trans(osb, handle);
|
||||
handle = NULL;
|
||||
|
||||
status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
status = ocfs2_commit_truncate(osb, inode, fe_bh, tc);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
}
|
||||
bail:
|
||||
out:
|
||||
if (handle)
|
||||
ocfs2_commit_trans(osb, handle);
|
||||
|
||||
mlog_exit(status);
|
||||
return status;
|
||||
}
|
||||
@@ -678,10 +663,10 @@ static int ocfs2_wipe_inode(struct inode *inode,
|
||||
struct inode *orphan_dir_inode = NULL;
|
||||
struct buffer_head *orphan_dir_bh = NULL;
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
struct ocfs2_dinode *di;
|
||||
|
||||
/* We've already voted on this so it should be readonly - no
|
||||
* spinlock needed. */
|
||||
orphaned_slot = OCFS2_I(inode)->ip_orphaned_slot;
|
||||
di = (struct ocfs2_dinode *) di_bh->b_data;
|
||||
orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
|
||||
|
||||
status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
|
||||
if (status)
|
||||
@@ -839,11 +824,20 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
|
||||
goto bail;
|
||||
}
|
||||
|
||||
status = ocfs2_request_delete_vote(inode);
|
||||
/* -EBUSY means that other nodes are still using the
|
||||
* inode. We're done here though, so avoid doing anything on
|
||||
* disk and let them worry about deleting it. */
|
||||
if (status == -EBUSY) {
|
||||
/*
|
||||
* This is how ocfs2 determines whether an inode is still live
|
||||
* within the cluster. Every node takes a shared read lock on
|
||||
* the inode open lock in ocfs2_read_locked_inode(). When we
|
||||
* get to ->delete_inode(), each node tries to convert it's
|
||||
* lock to an exclusive. Trylocks are serialized by the inode
|
||||
* meta data lock. If the upconvert suceeds, we know the inode
|
||||
* is no longer live and can be deleted.
|
||||
*
|
||||
* Though we call this with the meta data lock held, the
|
||||
* trylock keeps us from ABBA deadlock.
|
||||
*/
|
||||
status = ocfs2_try_open_lock(inode, 1);
|
||||
if (status == -EAGAIN) {
|
||||
status = 0;
|
||||
mlog(0, "Skipping delete of %llu because it is in use on"
|
||||
"other nodes\n", (unsigned long long)oi->ip_blkno);
|
||||
@@ -854,21 +848,10 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
|
||||
goto bail;
|
||||
}
|
||||
|
||||
spin_lock(&oi->ip_lock);
|
||||
if (oi->ip_orphaned_slot == OCFS2_INVALID_SLOT) {
|
||||
/* Nobody knew which slot this inode was orphaned
|
||||
* into. This may happen during node death and
|
||||
* recovery knows how to clean it up so we can safely
|
||||
* ignore this inode for now on. */
|
||||
mlog(0, "Nobody knew where inode %llu was orphaned!\n",
|
||||
(unsigned long long)oi->ip_blkno);
|
||||
} else {
|
||||
*wipe = 1;
|
||||
|
||||
mlog(0, "Inode %llu is ok to wipe from orphan dir %d\n",
|
||||
(unsigned long long)oi->ip_blkno, oi->ip_orphaned_slot);
|
||||
}
|
||||
spin_unlock(&oi->ip_lock);
|
||||
*wipe = 1;
|
||||
mlog(0, "Inode %llu is ok to wipe from orphan dir %u\n",
|
||||
(unsigned long long)oi->ip_blkno,
|
||||
le16_to_cpu(di->i_orphaned_slot));
|
||||
|
||||
bail:
|
||||
return status;
|
||||
@@ -1001,11 +984,16 @@ void ocfs2_clear_inode(struct inode *inode)
|
||||
mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,
|
||||
"Inode=%lu\n", inode->i_ino);
|
||||
|
||||
/* For remove delete_inode vote, we hold open lock before,
|
||||
* now it is time to unlock PR and EX open locks. */
|
||||
ocfs2_open_unlock(inode);
|
||||
|
||||
/* Do these before all the other work so that we don't bounce
|
||||
* the vote thread while waiting to destroy the locks. */
|
||||
ocfs2_mark_lockres_freeing(&oi->ip_rw_lockres);
|
||||
ocfs2_mark_lockres_freeing(&oi->ip_meta_lockres);
|
||||
ocfs2_mark_lockres_freeing(&oi->ip_data_lockres);
|
||||
ocfs2_mark_lockres_freeing(&oi->ip_open_lockres);
|
||||
|
||||
/* We very well may get a clear_inode before all an inodes
|
||||
* metadata has hit disk. Of course, we can't drop any cluster
|
||||
@@ -1020,8 +1008,7 @@ void ocfs2_clear_inode(struct inode *inode)
|
||||
"Clear inode of %llu, inode has io markers\n",
|
||||
(unsigned long long)oi->ip_blkno);
|
||||
|
||||
ocfs2_extent_map_drop(inode, 0);
|
||||
ocfs2_extent_map_init(inode);
|
||||
ocfs2_extent_map_trunc(inode, 0);
|
||||
|
||||
status = ocfs2_drop_inode_locks(inode);
|
||||
if (status < 0)
|
||||
@@ -1030,6 +1017,7 @@ void ocfs2_clear_inode(struct inode *inode)
|
||||
ocfs2_lock_res_free(&oi->ip_rw_lockres);
|
||||
ocfs2_lock_res_free(&oi->ip_meta_lockres);
|
||||
ocfs2_lock_res_free(&oi->ip_data_lockres);
|
||||
ocfs2_lock_res_free(&oi->ip_open_lockres);
|
||||
|
||||
ocfs2_metadata_cache_purge(inode);
|
||||
|
||||
@@ -1086,9 +1074,6 @@ void ocfs2_drop_inode(struct inode *inode)
|
||||
mlog(0, "Drop inode %llu, nlink = %u, ip_flags = 0x%x\n",
|
||||
(unsigned long long)oi->ip_blkno, inode->i_nlink, oi->ip_flags);
|
||||
|
||||
/* Testing ip_orphaned_slot here wouldn't work because we may
|
||||
* not have gotten a delete_inode vote from any other nodes
|
||||
* yet. */
|
||||
if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)
|
||||
generic_delete_inode(inode);
|
||||
else
|
||||
@@ -1121,8 +1106,8 @@ struct buffer_head *ocfs2_bread(struct inode *inode,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmperr = ocfs2_extent_map_get_blocks(inode, block, 1,
|
||||
&p_blkno, NULL);
|
||||
tmperr = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL,
|
||||
NULL);
|
||||
if (tmperr < 0) {
|
||||
mlog_errno(tmperr);
|
||||
goto fail;
|
||||
@@ -1259,7 +1244,7 @@ void ocfs2_refresh_inode(struct inode *inode,
|
||||
if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
|
||||
inode->i_blocks = 0;
|
||||
else
|
||||
inode->i_blocks = ocfs2_align_bytes_to_sectors(i_size_read(inode));
|
||||
inode->i_blocks = ocfs2_inode_sector_count(inode);
|
||||
inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
|
||||
inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
|
||||
inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
|
||||
|
||||
+14
-9
@@ -26,6 +26,8 @@
|
||||
#ifndef OCFS2_INODE_H
|
||||
#define OCFS2_INODE_H
|
||||
|
||||
#include "extent_map.h"
|
||||
|
||||
/* OCFS2 Inode Private Data */
|
||||
struct ocfs2_inode_info
|
||||
{
|
||||
@@ -34,6 +36,7 @@ struct ocfs2_inode_info
|
||||
struct ocfs2_lock_res ip_rw_lockres;
|
||||
struct ocfs2_lock_res ip_meta_lockres;
|
||||
struct ocfs2_lock_res ip_data_lockres;
|
||||
struct ocfs2_lock_res ip_open_lockres;
|
||||
|
||||
/* protects allocation changes on this inode. */
|
||||
struct rw_semaphore ip_alloc_sem;
|
||||
@@ -42,9 +45,7 @@ struct ocfs2_inode_info
|
||||
spinlock_t ip_lock;
|
||||
u32 ip_open_count;
|
||||
u32 ip_clusters;
|
||||
struct ocfs2_extent_map ip_map;
|
||||
struct list_head ip_io_markers;
|
||||
int ip_orphaned_slot;
|
||||
|
||||
struct mutex ip_io_mutex;
|
||||
|
||||
@@ -64,6 +65,8 @@ struct ocfs2_inode_info
|
||||
|
||||
struct ocfs2_caching_info ip_metadata_cache;
|
||||
|
||||
struct ocfs2_extent_map ip_extent_map;
|
||||
|
||||
struct inode vfs_inode;
|
||||
};
|
||||
|
||||
@@ -117,14 +120,9 @@ void ocfs2_delete_inode(struct inode *inode);
|
||||
void ocfs2_drop_inode(struct inode *inode);
|
||||
|
||||
/* Flags for ocfs2_iget() */
|
||||
#define OCFS2_FI_FLAG_NOWAIT 0x1
|
||||
#define OCFS2_FI_FLAG_DELETE 0x2
|
||||
#define OCFS2_FI_FLAG_SYSFILE 0x4
|
||||
#define OCFS2_FI_FLAG_NOLOCK 0x8
|
||||
#define OCFS2_FI_FLAG_SYSFILE 0x4
|
||||
#define OCFS2_FI_FLAG_ORPHAN_RECOVERY 0x8
|
||||
struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 feoff, int flags);
|
||||
struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
|
||||
u64 blkno,
|
||||
int delete_vote);
|
||||
int ocfs2_inode_init_private(struct inode *inode);
|
||||
int ocfs2_inode_revalidate(struct dentry *dentry);
|
||||
int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
|
||||
@@ -144,4 +142,11 @@ int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb);
|
||||
|
||||
void ocfs2_set_inode_flags(struct inode *inode);
|
||||
|
||||
static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
|
||||
{
|
||||
int c_to_s_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits - 9;
|
||||
|
||||
return (blkcnt_t)(OCFS2_I(inode)->ip_clusters << c_to_s_bits);
|
||||
}
|
||||
|
||||
#endif /* OCFS2_INODE_H */
|
||||
|
||||
+7
-17
@@ -649,29 +649,20 @@ bail:
|
||||
static int ocfs2_force_read_journal(struct inode *inode)
|
||||
{
|
||||
int status = 0;
|
||||
int i, p_blocks;
|
||||
u64 v_blkno, p_blkno;
|
||||
#define CONCURRENT_JOURNAL_FILL 32
|
||||
int i;
|
||||
u64 v_blkno, p_blkno, p_blocks, num_blocks;
|
||||
#define CONCURRENT_JOURNAL_FILL 32ULL
|
||||
struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
|
||||
|
||||
mlog_entry_void();
|
||||
|
||||
BUG_ON(inode->i_blocks !=
|
||||
ocfs2_align_bytes_to_sectors(i_size_read(inode)));
|
||||
|
||||
memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
|
||||
|
||||
mlog(0, "Force reading %llu blocks\n",
|
||||
(unsigned long long)(inode->i_blocks >>
|
||||
(inode->i_sb->s_blocksize_bits - 9)));
|
||||
|
||||
num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, inode->i_size);
|
||||
v_blkno = 0;
|
||||
while (v_blkno <
|
||||
(inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9))) {
|
||||
|
||||
while (v_blkno < num_blocks) {
|
||||
status = ocfs2_extent_map_get_blocks(inode, v_blkno,
|
||||
1, &p_blkno,
|
||||
&p_blocks);
|
||||
&p_blkno, &p_blocks, NULL);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto bail;
|
||||
@@ -1306,7 +1297,7 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
|
||||
continue;
|
||||
|
||||
iter = ocfs2_iget(osb, le64_to_cpu(de->inode),
|
||||
OCFS2_FI_FLAG_NOLOCK);
|
||||
OCFS2_FI_FLAG_ORPHAN_RECOVERY);
|
||||
if (IS_ERR(iter))
|
||||
continue;
|
||||
|
||||
@@ -1418,7 +1409,6 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb,
|
||||
/* Set the proper information to get us going into
|
||||
* ocfs2_delete_inode. */
|
||||
oi->ip_flags |= OCFS2_INODE_MAYBE_ORPHANED;
|
||||
oi->ip_orphaned_slot = slot;
|
||||
spin_unlock(&oi->ip_lock);
|
||||
|
||||
iput(inode);
|
||||
|
||||
+1
-1
@@ -390,7 +390,7 @@ static inline int ocfs2_calc_tree_trunc_credits(struct super_block *sb,
|
||||
/* We may be deleting metadata blocks, so metadata alloc dinode +
|
||||
one desc. block for each possible delete. */
|
||||
if (tree_depth && next_free == 1 &&
|
||||
le32_to_cpu(last_el->l_recs[i].e_clusters) == clusters_to_del)
|
||||
ocfs2_rec_clusters(last_el, &last_el->l_recs[i]) == clusters_to_del)
|
||||
credits += 1 + tree_depth;
|
||||
|
||||
/* update to the truncate log. */
|
||||
|
||||
+5
-2
@@ -85,8 +85,11 @@ int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
int ret = 0, lock_level = 0;
|
||||
struct ocfs2_super *osb = OCFS2_SB(file->f_dentry->d_inode->i_sb);
|
||||
|
||||
/* We don't want to support shared writable mappings yet. */
|
||||
if (!ocfs2_mount_local(osb) &&
|
||||
/*
|
||||
* Only support shared writeable mmap for local mounts which
|
||||
* don't know about holes.
|
||||
*/
|
||||
if ((!ocfs2_mount_local(osb) || ocfs2_sparse_alloc(osb)) &&
|
||||
((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) &&
|
||||
((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
|
||||
mlog(0, "disallow shared writable mmaps %lx\n", vma->vm_flags);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user