Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes: [GFS2] Revert remounting w/o acl option leaves acls enabled [GFS2] Fix setting of inherit jdata attr [GFS2] Fix incorrect error path in prepare_write() [GFS2] Fix incorrect return code in rgrp.c [GFS2] soft lockup in rgblk_search [GFS2] soft lockup detected in databuf_lo_before_commit [DLM] fix basts for granted PR waiting CW [DLM] More othercon fixes [DLM] Fix memory leak in dlm_add_member() when dlm_node_weight() returns less than zero [DLM] zero unused parts of sockaddr_storage [DLM] fix NULL ls usage [DLM] Clear othercon pointers when a connection is closed
This commit is contained in:
commit
28e8351ac2
@ -1670,9 +1670,10 @@ static int can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now,
|
|||||||
with a deadlk here, we'd have to generate something like grant_lock with
|
with a deadlk here, we'd have to generate something like grant_lock with
|
||||||
the deadlk error.) */
|
the deadlk error.) */
|
||||||
|
|
||||||
/* returns the highest requested mode of all blocked conversions */
|
/* Returns the highest requested mode of all blocked conversions; sets
|
||||||
|
cw if there's a blocked conversion to DLM_LOCK_CW. */
|
||||||
|
|
||||||
static int grant_pending_convert(struct dlm_rsb *r, int high)
|
static int grant_pending_convert(struct dlm_rsb *r, int high, int *cw)
|
||||||
{
|
{
|
||||||
struct dlm_lkb *lkb, *s;
|
struct dlm_lkb *lkb, *s;
|
||||||
int hi, demoted, quit, grant_restart, demote_restart;
|
int hi, demoted, quit, grant_restart, demote_restart;
|
||||||
@ -1709,6 +1710,9 @@ static int grant_pending_convert(struct dlm_rsb *r, int high)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hi = max_t(int, lkb->lkb_rqmode, hi);
|
hi = max_t(int, lkb->lkb_rqmode, hi);
|
||||||
|
|
||||||
|
if (cw && lkb->lkb_rqmode == DLM_LOCK_CW)
|
||||||
|
*cw = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grant_restart)
|
if (grant_restart)
|
||||||
@ -1721,29 +1725,52 @@ static int grant_pending_convert(struct dlm_rsb *r, int high)
|
|||||||
return max_t(int, high, hi);
|
return max_t(int, high, hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int grant_pending_wait(struct dlm_rsb *r, int high)
|
static int grant_pending_wait(struct dlm_rsb *r, int high, int *cw)
|
||||||
{
|
{
|
||||||
struct dlm_lkb *lkb, *s;
|
struct dlm_lkb *lkb, *s;
|
||||||
|
|
||||||
list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) {
|
list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) {
|
||||||
if (can_be_granted(r, lkb, 0, NULL))
|
if (can_be_granted(r, lkb, 0, NULL))
|
||||||
grant_lock_pending(r, lkb);
|
grant_lock_pending(r, lkb);
|
||||||
else
|
else {
|
||||||
high = max_t(int, lkb->lkb_rqmode, high);
|
high = max_t(int, lkb->lkb_rqmode, high);
|
||||||
|
if (lkb->lkb_rqmode == DLM_LOCK_CW)
|
||||||
|
*cw = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return high;
|
return high;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* cw of 1 means there's a lock with a rqmode of DLM_LOCK_CW that's blocked
|
||||||
|
on either the convert or waiting queue.
|
||||||
|
high is the largest rqmode of all locks blocked on the convert or
|
||||||
|
waiting queue. */
|
||||||
|
|
||||||
|
static int lock_requires_bast(struct dlm_lkb *gr, int high, int cw)
|
||||||
|
{
|
||||||
|
if (gr->lkb_grmode == DLM_LOCK_PR && cw) {
|
||||||
|
if (gr->lkb_highbast < DLM_LOCK_EX)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gr->lkb_highbast < high &&
|
||||||
|
!__dlm_compat_matrix[gr->lkb_grmode+1][high+1])
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void grant_pending_locks(struct dlm_rsb *r)
|
static void grant_pending_locks(struct dlm_rsb *r)
|
||||||
{
|
{
|
||||||
struct dlm_lkb *lkb, *s;
|
struct dlm_lkb *lkb, *s;
|
||||||
int high = DLM_LOCK_IV;
|
int high = DLM_LOCK_IV;
|
||||||
|
int cw = 0;
|
||||||
|
|
||||||
DLM_ASSERT(is_master(r), dlm_dump_rsb(r););
|
DLM_ASSERT(is_master(r), dlm_dump_rsb(r););
|
||||||
|
|
||||||
high = grant_pending_convert(r, high);
|
high = grant_pending_convert(r, high, &cw);
|
||||||
high = grant_pending_wait(r, high);
|
high = grant_pending_wait(r, high, &cw);
|
||||||
|
|
||||||
if (high == DLM_LOCK_IV)
|
if (high == DLM_LOCK_IV)
|
||||||
return;
|
return;
|
||||||
@ -1751,27 +1778,41 @@ static void grant_pending_locks(struct dlm_rsb *r)
|
|||||||
/*
|
/*
|
||||||
* If there are locks left on the wait/convert queue then send blocking
|
* If there are locks left on the wait/convert queue then send blocking
|
||||||
* ASTs to granted locks based on the largest requested mode (high)
|
* ASTs to granted locks based on the largest requested mode (high)
|
||||||
* found above. FIXME: highbast < high comparison not valid for PR/CW.
|
* found above.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) {
|
list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) {
|
||||||
if (lkb->lkb_bastaddr && (lkb->lkb_highbast < high) &&
|
if (lkb->lkb_bastaddr && lock_requires_bast(lkb, high, cw)) {
|
||||||
!__dlm_compat_matrix[lkb->lkb_grmode+1][high+1]) {
|
if (cw && high == DLM_LOCK_PR)
|
||||||
queue_bast(r, lkb, high);
|
queue_bast(r, lkb, DLM_LOCK_CW);
|
||||||
|
else
|
||||||
|
queue_bast(r, lkb, high);
|
||||||
lkb->lkb_highbast = high;
|
lkb->lkb_highbast = high;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int modes_require_bast(struct dlm_lkb *gr, struct dlm_lkb *rq)
|
||||||
|
{
|
||||||
|
if ((gr->lkb_grmode == DLM_LOCK_PR && rq->lkb_rqmode == DLM_LOCK_CW) ||
|
||||||
|
(gr->lkb_grmode == DLM_LOCK_CW && rq->lkb_rqmode == DLM_LOCK_PR)) {
|
||||||
|
if (gr->lkb_highbast < DLM_LOCK_EX)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gr->lkb_highbast < rq->lkb_rqmode && !modes_compat(gr, rq))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void send_bast_queue(struct dlm_rsb *r, struct list_head *head,
|
static void send_bast_queue(struct dlm_rsb *r, struct list_head *head,
|
||||||
struct dlm_lkb *lkb)
|
struct dlm_lkb *lkb)
|
||||||
{
|
{
|
||||||
struct dlm_lkb *gr;
|
struct dlm_lkb *gr;
|
||||||
|
|
||||||
list_for_each_entry(gr, head, lkb_statequeue) {
|
list_for_each_entry(gr, head, lkb_statequeue) {
|
||||||
if (gr->lkb_bastaddr &&
|
if (gr->lkb_bastaddr && modes_require_bast(gr, lkb)) {
|
||||||
gr->lkb_highbast < lkb->lkb_rqmode &&
|
|
||||||
!modes_compat(gr, lkb)) {
|
|
||||||
queue_bast(r, gr, lkb->lkb_rqmode);
|
queue_bast(r, gr, lkb->lkb_rqmode);
|
||||||
gr->lkb_highbast = lkb->lkb_rqmode;
|
gr->lkb_highbast = lkb->lkb_rqmode;
|
||||||
}
|
}
|
||||||
@ -2235,7 +2276,7 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
|
|||||||
before we try again to grant this one. */
|
before we try again to grant this one. */
|
||||||
|
|
||||||
if (is_demoted(lkb)) {
|
if (is_demoted(lkb)) {
|
||||||
grant_pending_convert(r, DLM_LOCK_IV);
|
grant_pending_convert(r, DLM_LOCK_IV, NULL);
|
||||||
if (_can_be_granted(r, lkb, 1)) {
|
if (_can_be_granted(r, lkb, 1)) {
|
||||||
grant_lock(r, lkb);
|
grant_lock(r, lkb);
|
||||||
queue_cast(r, lkb, 0);
|
queue_cast(r, lkb, 0);
|
||||||
|
@ -313,6 +313,7 @@ static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port,
|
|||||||
in6_addr->sin6_port = cpu_to_be16(port);
|
in6_addr->sin6_port = cpu_to_be16(port);
|
||||||
*addr_len = sizeof(struct sockaddr_in6);
|
*addr_len = sizeof(struct sockaddr_in6);
|
||||||
}
|
}
|
||||||
|
memset((char *)saddr + *addr_len, 0, sizeof(struct sockaddr_storage) - *addr_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close a remote connection and tidy up */
|
/* Close a remote connection and tidy up */
|
||||||
@ -332,8 +333,19 @@ static void close_connection(struct connection *con, bool and_other)
|
|||||||
__free_page(con->rx_page);
|
__free_page(con->rx_page);
|
||||||
con->rx_page = NULL;
|
con->rx_page = NULL;
|
||||||
}
|
}
|
||||||
con->retries = 0;
|
|
||||||
mutex_unlock(&con->sock_mutex);
|
/* If we are an 'othercon' then NULL the pointer to us
|
||||||
|
from the parent and tidy ourself up */
|
||||||
|
if (test_bit(CF_IS_OTHERCON, &con->flags)) {
|
||||||
|
struct connection *parent = __nodeid2con(con->nodeid, 0);
|
||||||
|
parent->othercon = NULL;
|
||||||
|
kmem_cache_free(con_cache, con);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Parent connections get reused */
|
||||||
|
con->retries = 0;
|
||||||
|
mutex_unlock(&con->sock_mutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We only send shutdown messages to nodes that are not part of the cluster */
|
/* We only send shutdown messages to nodes that are not part of the cluster */
|
||||||
@ -631,7 +643,7 @@ static int receive_from_sock(struct connection *con)
|
|||||||
|
|
||||||
out_close:
|
out_close:
|
||||||
mutex_unlock(&con->sock_mutex);
|
mutex_unlock(&con->sock_mutex);
|
||||||
if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) {
|
if (ret != -EAGAIN) {
|
||||||
close_connection(con, false);
|
close_connection(con, false);
|
||||||
/* Reconnect when there is something to send */
|
/* Reconnect when there is something to send */
|
||||||
}
|
}
|
||||||
@ -1122,8 +1134,6 @@ static int tcp_listen_for_all(void)
|
|||||||
|
|
||||||
log_print("Using TCP for communications");
|
log_print("Using TCP for communications");
|
||||||
|
|
||||||
set_bit(CF_IS_OTHERCON, &con->flags);
|
|
||||||
|
|
||||||
sock = tcp_create_listen_sock(con, dlm_local_addr[0]);
|
sock = tcp_create_listen_sock(con, dlm_local_addr[0]);
|
||||||
if (sock) {
|
if (sock) {
|
||||||
add_sock(sock, con);
|
add_sock(sock, con);
|
||||||
@ -1407,7 +1417,7 @@ void dlm_lowcomms_stop(void)
|
|||||||
for (i = 0; i <= max_nodeid; i++) {
|
for (i = 0; i <= max_nodeid; i++) {
|
||||||
con = __nodeid2con(i, 0);
|
con = __nodeid2con(i, 0);
|
||||||
if (con) {
|
if (con) {
|
||||||
con->flags |= 0xFF;
|
con->flags |= 0x0F;
|
||||||
if (con->sock)
|
if (con->sock)
|
||||||
con->sock->sk->sk_user_data = NULL;
|
con->sock->sk->sk_user_data = NULL;
|
||||||
}
|
}
|
||||||
@ -1423,8 +1433,6 @@ void dlm_lowcomms_stop(void)
|
|||||||
con = __nodeid2con(i, 0);
|
con = __nodeid2con(i, 0);
|
||||||
if (con) {
|
if (con) {
|
||||||
close_connection(con, true);
|
close_connection(con, true);
|
||||||
if (con->othercon)
|
|
||||||
kmem_cache_free(con_cache, con->othercon);
|
|
||||||
kmem_cache_free(con_cache, con);
|
kmem_cache_free(con_cache, con);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,10 @@ static int dlm_add_member(struct dlm_ls *ls, int nodeid)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
w = dlm_node_weight(ls->ls_name, nodeid);
|
w = dlm_node_weight(ls->ls_name, nodeid);
|
||||||
if (w < 0)
|
if (w < 0) {
|
||||||
|
kfree(memb);
|
||||||
return w;
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
memb->nodeid = nodeid;
|
memb->nodeid = nodeid;
|
||||||
memb->weight = w;
|
memb->weight = w;
|
||||||
|
@ -386,8 +386,7 @@ static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in)
|
|||||||
dlm_recover_process_copy(ls, rc_in);
|
dlm_recover_process_copy(ls, rc_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_ls_not_ready(struct dlm_ls *ls, int nodeid,
|
static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in)
|
||||||
struct dlm_rcom *rc_in)
|
|
||||||
{
|
{
|
||||||
struct dlm_rcom *rc;
|
struct dlm_rcom *rc;
|
||||||
struct rcom_config *rf;
|
struct rcom_config *rf;
|
||||||
@ -395,7 +394,7 @@ static int send_ls_not_ready(struct dlm_ls *ls, int nodeid,
|
|||||||
char *mb;
|
char *mb;
|
||||||
int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
|
int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
|
||||||
|
|
||||||
mh = dlm_lowcomms_get_buffer(nodeid, mb_len, ls->ls_allocation, &mb);
|
mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_NOFS, &mb);
|
||||||
if (!mh)
|
if (!mh)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
memset(mb, 0, mb_len);
|
memset(mb, 0, mb_len);
|
||||||
@ -465,7 +464,7 @@ void dlm_receive_rcom(struct dlm_header *hd, int nodeid)
|
|||||||
log_print("lockspace %x from %d type %x not found",
|
log_print("lockspace %x from %d type %x not found",
|
||||||
hd->h_lockspace, nodeid, rc->rc_type);
|
hd->h_lockspace, nodeid, rc->rc_type);
|
||||||
if (rc->rc_type == DLM_RCOM_STATUS)
|
if (rc->rc_type == DLM_RCOM_STATUS)
|
||||||
send_ls_not_ready(ls, nodeid, rc);
|
send_ls_not_ready(nodeid, rc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,8 +486,8 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
|
|||||||
gfs2_pin(sdp, bd->bd_bh);
|
gfs2_pin(sdp, bd->bd_bh);
|
||||||
tr->tr_num_databuf_new++;
|
tr->tr_num_databuf_new++;
|
||||||
}
|
}
|
||||||
sdp->sd_log_num_databuf++;
|
|
||||||
gfs2_log_lock(sdp);
|
gfs2_log_lock(sdp);
|
||||||
|
sdp->sd_log_num_databuf++;
|
||||||
list_add(&le->le_list, &sdp->sd_log_le_databuf);
|
list_add(&le->le_list, &sdp->sd_log_le_databuf);
|
||||||
gfs2_log_unlock(sdp);
|
gfs2_log_unlock(sdp);
|
||||||
}
|
}
|
||||||
@ -523,7 +523,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
|
|||||||
struct buffer_head *bh = NULL,*bh1 = NULL;
|
struct buffer_head *bh = NULL,*bh1 = NULL;
|
||||||
struct gfs2_log_descriptor *ld;
|
struct gfs2_log_descriptor *ld;
|
||||||
unsigned int limit;
|
unsigned int limit;
|
||||||
unsigned int total_dbuf = sdp->sd_log_num_databuf;
|
unsigned int total_dbuf;
|
||||||
unsigned int total_jdata = sdp->sd_log_num_jdata;
|
unsigned int total_jdata = sdp->sd_log_num_jdata;
|
||||||
unsigned int num, n;
|
unsigned int num, n;
|
||||||
__be64 *ptr = NULL;
|
__be64 *ptr = NULL;
|
||||||
@ -535,6 +535,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
|
|||||||
* into the log along with a header
|
* into the log along with a header
|
||||||
*/
|
*/
|
||||||
gfs2_log_lock(sdp);
|
gfs2_log_lock(sdp);
|
||||||
|
total_dbuf = sdp->sd_log_num_databuf;
|
||||||
bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf,
|
bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf,
|
||||||
bd_le.le_list);
|
bd_le.le_list);
|
||||||
while(total_dbuf) {
|
while(total_dbuf) {
|
||||||
@ -653,6 +654,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bh = NULL;
|
bh = NULL;
|
||||||
|
BUG_ON(total_dbuf < num);
|
||||||
total_dbuf -= num;
|
total_dbuf -= num;
|
||||||
total_jdata -= num;
|
total_jdata -= num;
|
||||||
}
|
}
|
||||||
|
@ -82,19 +82,20 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
|
|||||||
char *options, *o, *v;
|
char *options, *o, *v;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
/* If someone preloaded options, use those instead */
|
if (!remount) {
|
||||||
spin_lock(&gfs2_sys_margs_lock);
|
/* If someone preloaded options, use those instead */
|
||||||
if (!remount && gfs2_sys_margs) {
|
spin_lock(&gfs2_sys_margs_lock);
|
||||||
data = gfs2_sys_margs;
|
if (gfs2_sys_margs) {
|
||||||
gfs2_sys_margs = NULL;
|
data = gfs2_sys_margs;
|
||||||
}
|
gfs2_sys_margs = NULL;
|
||||||
spin_unlock(&gfs2_sys_margs_lock);
|
}
|
||||||
|
spin_unlock(&gfs2_sys_margs_lock);
|
||||||
|
|
||||||
/* Set some defaults */
|
/* Set some defaults */
|
||||||
memset(args, 0, sizeof(struct gfs2_args));
|
args->ar_num_glockd = GFS2_GLOCKD_DEFAULT;
|
||||||
args->ar_num_glockd = GFS2_GLOCKD_DEFAULT;
|
args->ar_quota = GFS2_QUOTA_DEFAULT;
|
||||||
args->ar_quota = GFS2_QUOTA_DEFAULT;
|
args->ar_data = GFS2_DATA_DEFAULT;
|
||||||
args->ar_data = GFS2_DATA_DEFAULT;
|
}
|
||||||
|
|
||||||
/* Split the options into tokens with the "," character and
|
/* Split the options into tokens with the "," character and
|
||||||
process them */
|
process them */
|
||||||
|
@ -416,7 +416,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page,
|
|||||||
|
|
||||||
error = gfs2_trans_begin(sdp, rblocks, 0);
|
error = gfs2_trans_begin(sdp, rblocks, 0);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out_trans_fail;
|
||||||
|
|
||||||
if (gfs2_is_stuffed(ip)) {
|
if (gfs2_is_stuffed(ip)) {
|
||||||
if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
|
if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
|
||||||
@ -434,6 +434,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page,
|
|||||||
out:
|
out:
|
||||||
if (error) {
|
if (error) {
|
||||||
gfs2_trans_end(sdp);
|
gfs2_trans_end(sdp);
|
||||||
|
out_trans_fail:
|
||||||
if (alloc_required) {
|
if (alloc_required) {
|
||||||
gfs2_inplace_release(ip);
|
gfs2_inplace_release(ip);
|
||||||
out_qunlock:
|
out_qunlock:
|
||||||
|
@ -177,8 +177,8 @@ static const u32 fsflags_to_gfs2[32] = {
|
|||||||
[5] = GFS2_DIF_APPENDONLY,
|
[5] = GFS2_DIF_APPENDONLY,
|
||||||
[7] = GFS2_DIF_NOATIME,
|
[7] = GFS2_DIF_NOATIME,
|
||||||
[12] = GFS2_DIF_EXHASH,
|
[12] = GFS2_DIF_EXHASH,
|
||||||
[14] = GFS2_DIF_JDATA,
|
[14] = GFS2_DIF_INHERIT_JDATA,
|
||||||
[20] = GFS2_DIF_DIRECTIO,
|
[20] = GFS2_DIF_INHERIT_DIRECTIO,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 gfs2_to_fsflags[32] = {
|
static const u32 gfs2_to_fsflags[32] = {
|
||||||
@ -187,8 +187,6 @@ static const u32 gfs2_to_fsflags[32] = {
|
|||||||
[gfs2fl_AppendOnly] = FS_APPEND_FL,
|
[gfs2fl_AppendOnly] = FS_APPEND_FL,
|
||||||
[gfs2fl_NoAtime] = FS_NOATIME_FL,
|
[gfs2fl_NoAtime] = FS_NOATIME_FL,
|
||||||
[gfs2fl_ExHash] = FS_INDEX_FL,
|
[gfs2fl_ExHash] = FS_INDEX_FL,
|
||||||
[gfs2fl_Jdata] = FS_JOURNAL_DATA_FL,
|
|
||||||
[gfs2fl_Directio] = FS_DIRECTIO_FL,
|
|
||||||
[gfs2fl_InheritDirectio] = FS_DIRECTIO_FL,
|
[gfs2fl_InheritDirectio] = FS_DIRECTIO_FL,
|
||||||
[gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
|
[gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
|
||||||
};
|
};
|
||||||
@ -207,6 +205,12 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
|
|||||||
return error;
|
return error;
|
||||||
|
|
||||||
fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags);
|
fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags);
|
||||||
|
if (!S_ISDIR(inode->i_mode)) {
|
||||||
|
if (ip->i_di.di_flags & GFS2_DIF_JDATA)
|
||||||
|
fsflags |= FS_JOURNAL_DATA_FL;
|
||||||
|
if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO)
|
||||||
|
fsflags |= FS_DIRECTIO_FL;
|
||||||
|
}
|
||||||
if (put_user(fsflags, ptr))
|
if (put_user(fsflags, ptr))
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
|
|
||||||
@ -270,13 +274,6 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
|
|||||||
if ((new_flags ^ flags) == 0)
|
if ((new_flags ^ flags) == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (S_ISDIR(inode->i_mode)) {
|
|
||||||
if ((new_flags ^ flags) & GFS2_DIF_JDATA)
|
|
||||||
new_flags ^= (GFS2_DIF_JDATA|GFS2_DIF_INHERIT_JDATA);
|
|
||||||
if ((new_flags ^ flags) & GFS2_DIF_DIRECTIO)
|
|
||||||
new_flags ^= (GFS2_DIF_DIRECTIO|GFS2_DIF_INHERIT_DIRECTIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
error = -EINVAL;
|
error = -EINVAL;
|
||||||
if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET)
|
if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET)
|
||||||
goto out;
|
goto out;
|
||||||
@ -315,11 +312,19 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask)
|
|||||||
|
|
||||||
static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
|
static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
|
||||||
{
|
{
|
||||||
|
struct inode *inode = filp->f_path.dentry->d_inode;
|
||||||
u32 fsflags, gfsflags;
|
u32 fsflags, gfsflags;
|
||||||
if (get_user(fsflags, ptr))
|
if (get_user(fsflags, ptr))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags);
|
gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags);
|
||||||
return do_gfs2_set_flags(filp, gfsflags, ~0);
|
if (!S_ISDIR(inode->i_mode)) {
|
||||||
|
if (gfsflags & GFS2_DIF_INHERIT_JDATA)
|
||||||
|
gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA);
|
||||||
|
if (gfsflags & GFS2_DIF_INHERIT_DIRECTIO)
|
||||||
|
gfsflags ^= (GFS2_DIF_DIRECTIO | GFS2_DIF_INHERIT_DIRECTIO);
|
||||||
|
return do_gfs2_set_flags(filp, gfsflags, ~0);
|
||||||
|
}
|
||||||
|
return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||||
|
@ -863,16 +863,19 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
|
|||||||
u64 no_addr;
|
u64 no_addr;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
if (goal >= rgd->rd_data)
|
||||||
|
break;
|
||||||
goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
|
goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
|
||||||
GFS2_BLKST_UNLINKED);
|
GFS2_BLKST_UNLINKED);
|
||||||
if (goal == 0)
|
if (goal == BFITNOENT)
|
||||||
return 0;
|
break;
|
||||||
no_addr = goal + rgd->rd_data0;
|
no_addr = goal + rgd->rd_data0;
|
||||||
if (no_addr <= *last_unlinked)
|
goal++;
|
||||||
|
if (no_addr < *last_unlinked)
|
||||||
continue;
|
continue;
|
||||||
*last_unlinked = no_addr;
|
*last_unlinked = no_addr;
|
||||||
inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN,
|
inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN,
|
||||||
no_addr, -1);
|
no_addr, -1);
|
||||||
if (!IS_ERR(inode))
|
if (!IS_ERR(inode))
|
||||||
return inode;
|
return inode;
|
||||||
}
|
}
|
||||||
@ -1313,7 +1316,7 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
|
|||||||
bi->bi_len, blk, new_state);
|
bi->bi_len, blk, new_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (blk == BFITNOENT) ? 0 : (bi->bi_start * GFS2_NBBY) + blk;
|
return (blk == BFITNOENT) ? blk : (bi->bi_start * GFS2_NBBY) + blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1393,6 +1396,7 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip)
|
|||||||
goal = rgd->rd_last_alloc_data;
|
goal = rgd->rd_last_alloc_data;
|
||||||
|
|
||||||
blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
|
blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
|
||||||
|
BUG_ON(blk == BFITNOENT);
|
||||||
rgd->rd_last_alloc_data = blk;
|
rgd->rd_last_alloc_data = blk;
|
||||||
|
|
||||||
block = rgd->rd_data0 + blk;
|
block = rgd->rd_data0 + blk;
|
||||||
@ -1437,6 +1441,7 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip)
|
|||||||
goal = rgd->rd_last_alloc_meta;
|
goal = rgd->rd_last_alloc_meta;
|
||||||
|
|
||||||
blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
|
blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
|
||||||
|
BUG_ON(blk == BFITNOENT);
|
||||||
rgd->rd_last_alloc_meta = blk;
|
rgd->rd_last_alloc_meta = blk;
|
||||||
|
|
||||||
block = rgd->rd_data0 + blk;
|
block = rgd->rd_data0 + blk;
|
||||||
@ -1478,6 +1483,7 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation)
|
|||||||
|
|
||||||
blk = rgblk_search(rgd, rgd->rd_last_alloc_meta,
|
blk = rgblk_search(rgd, rgd->rd_last_alloc_meta,
|
||||||
GFS2_BLKST_FREE, GFS2_BLKST_DINODE);
|
GFS2_BLKST_FREE, GFS2_BLKST_DINODE);
|
||||||
|
BUG_ON(blk == BFITNOENT);
|
||||||
|
|
||||||
rgd->rd_last_alloc_meta = blk;
|
rgd->rd_last_alloc_meta = blk;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user