From ccde9866c8679c37f1dcd0309100986e1d1c2041 Mon Sep 17 00:00:00 2001 From: pschwan Date: Sat, 15 Jun 2002 23:38:26 +0000 Subject: [PATCH] - Fixed serious LDLM bugs, including mistaking the lock _type_ for the lock _mode_ in llight's file data lock conversion - Fixed delayed-create-on-open bug - prepare_write was zeroing out way too much of the page. fixed. - when mdc locks are revoked, don't invalidate a non-directory inode's pages - increase timeouts to 100 --- lustre/include/linux/lustre_dlm.h | 9 +++++---- lustre/include/linux/lustre_mds.h | 2 +- lustre/ldlm/ldlm_resource.c | 2 +- lustre/llite/file.c | 20 +++++++++++--------- lustre/llite/namei.c | 4 ++++ lustre/llite/rw.c | 15 +++++---------- lustre/llite/super.c | 2 +- lustre/mdc/mdc_request.c | 26 +++++++++++++++++++------- lustre/mds/handler.c | 2 -- lustre/mds/mds_extN.c | 2 ++ lustre/mds/mds_reint.c | 6 ++++-- lustre/osc/osc_request.c | 2 +- lustre/ptlrpc/client.c | 4 ++-- 13 files changed, 56 insertions(+), 40 deletions(-) diff --git a/lustre/include/linux/lustre_dlm.h b/lustre/include/linux/lustre_dlm.h index 85c4638..eec8407 100644 --- a/lustre/include/linux/lustre_dlm.h +++ b/lustre/include/linux/lustre_dlm.h @@ -139,11 +139,12 @@ typedef int (*ldlm_res_compat)(struct ldlm_lock *child, struct ldlm_lock *new); typedef int (*ldlm_res_policy)(struct ldlm_lock *lock, void *req_cookie, ldlm_mode_t mode, void *data); -#define LDLM_PLAIN 0 -#define LDLM_EXTENT 1 -#define LDLM_MDSINTENT 2 +#define LDLM_PLAIN 10 +#define LDLM_EXTENT 11 +#define LDLM_MDSINTENT 12 -#define LDLM_MAX_TYPE 2 +#define LDLM_MIN_TYPE 10 +#define LDLM_MAX_TYPE 12 extern ldlm_res_compat ldlm_res_compat_table []; extern ldlm_res_policy ldlm_res_policy_table []; diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h index b96207a..52b034a 100644 --- a/lustre/include/linux/lustre_mds.h +++ b/lustre/include/linux/lustre_mds.h @@ -156,7 +156,7 @@ int mdc_getattr(struct obd_conn *conn, int mdc_setattr(struct obd_conn *conn, struct inode *, struct iattr *iattr, struct ptlrpc_request **); int mdc_open(struct obd_conn *conn, - ino_t ino, int type, int flags, __u64 objid, __u64 cookie, + ino_t ino, int type, int flags, struct obdo *obdo, __u64 cookie, __u64 *fh, struct ptlrpc_request **request); int mdc_close(struct obd_conn *conn, ino_t ino, int type, __u64 fh, struct ptlrpc_request **req); diff --git a/lustre/ldlm/ldlm_resource.c b/lustre/ldlm/ldlm_resource.c index da263a7..99d00b8 100644 --- a/lustre/ldlm/ldlm_resource.c +++ b/lustre/ldlm/ldlm_resource.c @@ -169,7 +169,7 @@ static struct ldlm_resource *ldlm_resource_add(struct ldlm_namespace *ns, struct ldlm_resource *res; ENTRY; - if (type < 0 || type > LDLM_MAX_TYPE) { + if (type < LDLM_MIN_TYPE || type > LDLM_MAX_TYPE) { LBUG(); RETURN(NULL); } diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 57e4cca..aa16333 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -36,10 +36,9 @@ static int ll_file_open(struct inode *inode, struct file *file) int rc; struct ptlrpc_request *req = NULL; struct ll_file_data *fd; - struct obdo *oa; + struct obdo *oa = NULL; struct ll_sb_info *sbi = ll_i2sbi(inode); struct ll_inode_info *lli = ll_i2info(inode); - __u64 id = 0; ENTRY; if (file->private_data) @@ -60,19 +59,13 @@ static int ll_file_open(struct inode *inode, struct file *file) lli->lli_flags &= ~OBD_FL_CREATEONOPEN; } - oa = lli->lli_obdo; - if (oa == NULL) { - LBUG(); - GOTO(out_mdc, rc = -EINVAL); - } - fd = kmem_cache_alloc(ll_file_data_slab, SLAB_KERNEL); if (!fd) GOTO(out, rc = -ENOMEM); memset(fd, 0, sizeof(*fd)); rc = mdc_open(&sbi->ll_mdc_conn, inode->i_ino, S_IFREG, file->f_flags, - id, (__u64)(unsigned long)file, &fd->fd_mdshandle, &req); + oa, (__u64)(unsigned long)file, &fd->fd_mdshandle, &req); fd->fd_req = req; ptlrpc_req_finished(req); if (rc) @@ -84,6 +77,12 @@ static int ll_file_open(struct inode *inode, struct file *file) if (!fd->fd_mdshandle) CERROR("mdc_open didn't assign fd_mdshandle\n"); + oa = lli->lli_obdo; + if (oa == NULL) { + LBUG(); + GOTO(out_mdc, rc = -EINVAL); + } + rc = obd_open(ll_i2obdconn(inode), oa); if (rc) GOTO(out_mdc, rc = -abs(rc)); @@ -214,6 +213,7 @@ static int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock *new, if (inode == NULL) LBUG(); down(&inode->i_sem); + CDEBUG(D_INODE, "invalidating obdo/inode %ld\n", inode->i_ino); invalidate_inode_pages(inode); up(&inode->i_sem); @@ -285,6 +285,8 @@ ll_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ENTRY; if (!(fd->fd_flags & LL_FILE_IGNORE_LOCK)) { + /* FIXME: this should check whether O_APPEND is set and adjust + * extent.start accordingly */ extent.start = *ppos; extent.end = *ppos + count; CDEBUG(D_INFO, "Locking inode %ld, start %Lu end %Lu\n", diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index f08914f..5d23512 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -171,8 +171,12 @@ static struct dentry *ll_lookup2(struct inode * dir, struct dentry *dentry, } offset = 0; } else { + struct mds_body *body; + offset = 1; request = (struct ptlrpc_request *)it->it_data; + body = lustre_msg_buf(request->rq_repmsg, 1); + type = body->mode; } if (S_ISREG(type)) { diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index eb5a602..c2b736a 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -61,8 +61,8 @@ static int ll_readpage(struct file *file, struct page *page) if (!PageLocked(page)) LBUG(); - if (((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT) <= page->index) { - memset(kmap(page), 0, PAGE_CACHE_SIZE); + if (((inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT) <= page->index) { + memset(kmap(page), 0, PAGE_SIZE); kunmap(page); GOTO(readpage_out, rc); } @@ -87,7 +87,7 @@ static int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { struct inode *inode = page->mapping->host; - obd_off offset = ((obd_off)page->index) << PAGE_SHIFT; + //obd_off offset = ((obd_off)page->index) << PAGE_SHIFT; int rc = 0; char *addr; ENTRY; @@ -99,17 +99,12 @@ static int ll_prepare_write(struct file *file, struct page *page, unsigned from, if (Page_Uptodate(page)) GOTO(prepare_done, rc); - if (offset + from >= inode->i_size) { - memset(addr, 0, PAGE_SIZE); - GOTO(prepare_done, rc); - } + memset(addr, 0, PAGE_SIZE); /* We're completely overwriting an existing page, so _don't_ set it up * to date until commit_write */ - if (from == 0 && to == PAGE_SIZE) { - memset(addr, 0, PAGE_SIZE); + if (from == 0 && to == PAGE_SIZE) RETURN(0); - } rc = ll_brw(OBD_BRW_READ, inode, page, 0); diff --git a/lustre/llite/super.c b/lustre/llite/super.c index 8ea85d5..434176a 100644 --- a/lustre/llite/super.c +++ b/lustre/llite/super.c @@ -394,7 +394,7 @@ static void inline ll_to_inode(struct inode *dst, struct ll_inode_md *md) dst->i_generation = body->generation; /* this will become more elaborate for striping etc */ - if (md->obdo != NULL) { + if (md->obdo != NULL && md->obdo->o_valid != 0) { ii->lli_obdo = obdo_alloc(); memcpy(ii->lli_obdo, md->obdo, sizeof(*md->obdo)); } diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 94b79aa..9830405 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -145,7 +145,10 @@ static int mdc_lock_callback(struct ldlm_lock *lock, struct ldlm_lock *new, /* FIXME: do something better than throwing away everything */ if (inode == NULL) LBUG(); - invalidate_inode_pages(inode); + if (S_ISDIR(inode->i_mode)) { + CDEBUG(D_INODE, "invalidating inode %ld\n", inode->i_ino); + invalidate_inode_pages(inode); + } rc = ldlm_cli_cancel(lock->l_client, lock); if (rc < 0) { @@ -201,7 +204,7 @@ int mdc_enqueue(struct obd_conn *conn, int lock_type, struct lookup_intent *it, /* pack the intended request */ mds_create_pack(req, 2, dir, it->it_mode, id, current->fsuid, - current->fsgid, CURRENT_TIME, de->d_name.name, + current->fsgid, CURRENT_TIME, de->d_name.name, de->d_name.len, tgt, tgtlen); size[0] = sizeof(struct ldlm_reply); @@ -285,7 +288,7 @@ int mdc_enqueue(struct obd_conn *conn, int lock_type, struct lookup_intent *it, } else { LBUG(); } - +#warning FIXME: the data here needs to be different if a lock was granted for a different inode rc = ldlm_cli_enqueue(mdc->mdc_ldlm_client, mdc->mdc_conn, req, obddev->obd_namespace, NULL, res_id, lock_type, NULL, 0, lock_mode, &flags, @@ -305,16 +308,22 @@ int mdc_enqueue(struct obd_conn *conn, int lock_type, struct lookup_intent *it, RETURN(0); } -int mdc_open(struct obd_conn *conn, ino_t ino, int type, int flags, __u64 objid, +int mdc_open(struct obd_conn *conn, ino_t ino, int type, int flags, + struct obdo *obdo, __u64 cookie, __u64 *fh, struct ptlrpc_request **request) { struct mdc_obd *mdc = mdc_conn2mdc(conn); struct mds_body *body; - int rc, size = sizeof(*body); + int rc, size[2] = {sizeof(*body)}, bufcount = 1; struct ptlrpc_request *req; + if (obdo != NULL) { + bufcount = 2; + size[1] = sizeof(*obdo); + } + req = ptlrpc_prep_req(mdc->mdc_client, mdc->mdc_conn, - MDS_OPEN, 1, &size, NULL); + MDS_OPEN, bufcount, size, NULL); if (!req) GOTO(out, rc = -ENOMEM); @@ -326,7 +335,10 @@ int mdc_open(struct obd_conn *conn, ino_t ino, int type, int flags, __u64 objid, body->flags = HTON__u32(flags); body->extra = cookie; - req->rq_replen = lustre_msg_size(1, &size); + if (obdo != NULL) + memcpy(lustre_msg_buf(req->rq_reqmsg, 1), obdo, sizeof(*obdo)); + + req->rq_replen = lustre_msg_size(1, size); rc = ptlrpc_queue_wait(req); rc = ptlrpc_check_status(req, rc); diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index ffdefee..36c3448 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -462,7 +462,6 @@ static int mds_open(struct ptlrpc_request *req) int rc, size = sizeof(*body); ENTRY; - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_OPEN_PACK)) { CERROR("mds: out of memory\n"); @@ -470,7 +469,6 @@ static int mds_open(struct ptlrpc_request *req) RETURN(0); } - mci = mds_uuid_to_mci(mds, ptlrpc_req_to_uuid(req)); if (!mci) { CERROR("mds: no mci!\n"); diff --git a/lustre/mds/mds_extN.c b/lustre/mds/mds_extN.c index 3068fe0..30f4d51 100644 --- a/lustre/mds/mds_extN.c +++ b/lustre/mds/mds_extN.c @@ -151,6 +151,8 @@ static int mds_extN_get_obdo(struct inode *inode, struct obdo *obdo) /* This field is byteswapped because it appears in the * catalogue. All others are opaque to the MDS */ obdo->o_id = le64_to_cpu(data->mo_lov_md.lmd_object_id); + obdo->o_mode = S_IFREG; + obdo->o_valid |= OBD_MD_FLID | OBD_MD_FLINLINE | OBD_MD_FLMODE; } #warning FIXME: pass this buffer to caller for transmission when size exceeds OBD_INLINESZ diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index a52c02f..6b95585 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -251,7 +251,9 @@ static int mds_reint_create(struct mds_update_record *rec, int offset, body = lustre_msg_buf(req->rq_repmsg, offset); mds_pack_inode2fid(&body->fid1, inode); mds_pack_inode2body(body, inode); - if (S_ISREG(inode->i_mode)) { +#warning FIXME: This ext3/N-specific code does not belong here + /* If i_file_acl is set, this inode has an EA */ + if (S_ISREG(inode->i_mode) && inode->u.ext3_i.i_file_acl) { obdo = lustre_msg_buf(req->rq_repmsg, offset + 1); mds_fs_get_obdo(mds, inode, obdo); } @@ -313,7 +315,7 @@ static int mds_reint_create(struct mds_update_record *rec, int offset, struct mds_body *body; CDEBUG(D_INODE, "created ino %ld\n", dchild->d_inode->i_ino); - if (type == S_IFREG) { + if (!offset && type == S_IFREG) { struct obdo *obdo; obdo = lustre_msg_buf(req->rq_reqmsg, 2); rc = mds_fs_set_obdo(mds, inode, handle, obdo); diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 0f5ec19..7590bfd 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -694,7 +694,7 @@ static int osc_enqueue(struct obd_conn *oconn, if (mode == LCK_PR) return 0; - rc = ldlm_cli_convert(cl, lockh, type, &flags); + rc = ldlm_cli_convert(cl, lockh, mode, &flags); if (rc) LBUG(); diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c index 0f575c4..01bee46 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -469,7 +469,7 @@ int ptlrpc_queue_wait(struct ptlrpc_request *req) } resend: req->rq_time = CURRENT_TIME; - req->rq_timeout = 15; + req->rq_timeout = 100; rc = ptl_send_rpc(req); if (rc) { CERROR("error %d, opcode %d\n", rc, req->rq_reqmsg->opc); @@ -541,7 +541,7 @@ int ptlrpc_replay_req(struct ptlrpc_request *req) req->rq_connection->c_level); req->rq_time = CURRENT_TIME; - req->rq_timeout = 15; + req->rq_timeout = 100; rc = ptl_send_rpc(req); if (rc) { CERROR("error %d, opcode %d\n", rc, req->rq_reqmsg->opc); -- 1.8.3.1