From 6f3d8ea4fc072430642aa93f31284ce89a09cb27 Mon Sep 17 00:00:00 2001 From: pschwan Date: Thu, 23 May 2002 20:52:49 +0000 Subject: [PATCH] - Fixed symlinks - Fixed connect-failure-leads-to-segfault bug --- lustre/include/linux/lustre_idl.h | 4 +++- lustre/include/linux/lustre_mds.h | 3 ++- lustre/llite/namei.c | 2 +- lustre/llite/super.c | 2 +- lustre/llite/symlink.c | 36 +++++++++++++++++++++--------- lustre/mdc/mdc_request.c | 14 +++++++----- lustre/mds/handler.c | 47 ++++++++++++++++++++++++++++----------- lustre/ptlrpc/client.c | 11 ++++----- 8 files changed, 81 insertions(+), 38 deletions(-) diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index a6783e9..f17fef2 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -156,7 +156,9 @@ struct obdo { #define OBD_MD_FLINLINE (0x00008000UL) #define OBD_MD_FLOBDMD (0x00010000UL) #define OBD_MD_FLOBJID (0x00020000UL) -#define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDMD | OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS)) +#define OBD_MD_LINKNAME (0x00040000UL) +#define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDMD | OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS |\ + OBD_MD_LINKNAME)) /* request structure for OST's */ diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h index 4395900..c1b3b55 100644 --- a/lustre/include/linux/lustre_mds.h +++ b/lustre/include/linux/lustre_mds.h @@ -128,7 +128,8 @@ int mdc_connect(struct ptlrpc_client *, struct ptlrpc_connection *, struct ll_fid *rootfid, __u64 *last_committed, __u64 *last_rcvd, __u32 *last_xid, struct ptlrpc_request **); int mdc_getattr(struct ptlrpc_client *, struct ptlrpc_connection *, ino_t ino, - int type, unsigned long valid, struct ptlrpc_request **); + int type, unsigned long valid, size_t ea_size, + struct ptlrpc_request **); int mdc_setattr(struct ptlrpc_client *, struct ptlrpc_connection *, struct inode *, struct iattr *iattr, struct ptlrpc_request **); int mdc_open(struct ptlrpc_client *, struct ptlrpc_connection *, ino_t ino, diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 095f0e5..16d4a0e 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -108,7 +108,7 @@ static struct dentry *ll_lookup(struct inode * dir, struct dentry *dentry) GOTO(negative, NULL); err = mdc_getattr(&sbi->ll_mds_client, sbi->ll_mds_conn, ino, type, - OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, &request); + OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request); if (err) { CERROR("failure %d inode %ld\n", err, (long)ino); ptlrpc_free_req(request); diff --git a/lustre/llite/super.c b/lustre/llite/super.c index 9735456..000502a 100644 --- a/lustre/llite/super.c +++ b/lustre/llite/super.c @@ -167,7 +167,7 @@ static struct super_block * ll_read_super(struct super_block *sb, /* make root inode */ err = mdc_getattr(&sbi->ll_mds_client, sbi->ll_mds_conn, sbi->ll_rootino, S_IFDIR, - OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, &request); + OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, 0, &request); if (err) { CERROR("mdc_getattr failed for root: rc = %d\n", err); GOTO(out_req, sb = NULL); diff --git a/lustre/llite/symlink.c b/lustre/llite/symlink.c index 5f54913..ab87a92 100644 --- a/lustre/llite/symlink.c +++ b/lustre/llite/symlink.c @@ -27,22 +27,36 @@ #include /* for ENTRY and EXIT only */ #include -static int ll_fast_readlink(struct dentry *dentry, char *buffer, int buflen) +static int ll_readlink(struct dentry *dentry, char *buffer, int buflen) { - char *s = ll_i2info(dentry->d_inode)->lli_inline; - return vfs_readlink(dentry, buffer, buflen, s); -} + struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode); + struct ptlrpc_request *request; + char *tmp; + int rc, size; + ENTRY; -static int ll_fast_follow_link(struct dentry *dentry, struct nameidata *nd) -{ - char *s = ll_i2info(dentry->d_inode)->lli_inline; - return vfs_follow_link(nd, s); + rc = mdc_getattr(&sbi->ll_mds_client, sbi->ll_mds_conn, + dentry->d_inode->i_ino, S_IFLNK, + OBD_MD_LINKNAME, dentry->d_inode->i_size, &request); + if (rc) { + CERROR("failure %d inode %ld\n", rc, + (long)dentry->d_inode->i_ino); + ptlrpc_free_req(request); + RETURN(rc); + } + + tmp = lustre_msg_buf(request->rq_repmsg, 1); + size = MIN(request->rq_repmsg->buflens[1], buflen); + rc = copy_to_user(buffer, tmp, size); + if (rc == 0) + rc = size; + + ptlrpc_free_req(request); + RETURN(rc); } extern int ll_setattr(struct dentry *de, struct iattr *attr); struct inode_operations ll_fast_symlink_inode_operations = { - readlink: ll_fast_readlink, - follow_link: ll_fast_follow_link, + readlink: ll_readlink, setattr: ll_setattr }; - diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 0e906a4..4be6294 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -79,15 +79,15 @@ int mdc_connect(struct ptlrpc_client *cl, struct ptlrpc_connection *conn, int mdc_getattr(struct ptlrpc_client *cl, struct ptlrpc_connection *conn, - ino_t ino, int type, unsigned long valid, + ino_t ino, int type, unsigned long valid, size_t ea_size, struct ptlrpc_request **request) { struct ptlrpc_request *req; struct mds_body *body; - int rc, size = sizeof(*body); + int rc, size[2] = {sizeof(*body), 0}, bufcount = 1; ENTRY; - req = ptlrpc_prep_req(cl, conn, MDS_GETATTR, 1, &size, NULL); + req = ptlrpc_prep_req(cl, conn, MDS_GETATTR, 1, size, NULL); if (!req) GOTO(out, rc = -ENOMEM); @@ -95,7 +95,11 @@ int mdc_getattr(struct ptlrpc_client *cl, struct ptlrpc_connection *conn, ll_ino2fid(&body->fid1, ino, 0, type); body->valid = valid; - req->rq_replen = lustre_msg_size(1, &size); + if (valid & OBD_MD_LINKNAME) { + bufcount = 2; + size[1] = ea_size; + } + req->rq_replen = lustre_msg_size(bufcount, size); req->rq_level = LUSTRE_CONN_FULL; rc = ptlrpc_queue_wait(req); @@ -263,7 +267,7 @@ static int request_ioctl(struct inode *inode, struct file *file, switch (cmd) { case IOC_REQUEST_GETATTR: { CERROR("-- getting attr for ino %lu\n", arg); - err = mdc_getattr(&cl, conn, arg, S_IFDIR, ~0, &request); + err = mdc_getattr(&cl, conn, arg, S_IFDIR, ~0, 0, &request); CERROR("-- done err %d\n", err); GOTO(out, err); diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index e22bbee..0ce5167 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -97,10 +97,9 @@ struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, (generation && inode->i_generation != generation)) { /* we didn't find the right inode.. */ CERROR("bad inode %lu, link: %d ct: %d or version %u/%u\n", - inode->i_ino, - inode->i_nlink, atomic_read(&inode->i_count), - inode->i_generation, - generation); + inode->i_ino, inode->i_nlink, + atomic_read(&inode->i_count), inode->i_generation, + generation); LBUG(); iput(inode); return ERR_PTR(-ESTALE); @@ -302,25 +301,46 @@ int mds_getattr(struct ptlrpc_request *req) struct inode *inode; struct mds_body *body; struct mds_obd *mds = &req->rq_obd->u.mds; - int rc, size = sizeof(*body); + int rc, size[2] = {sizeof(*body)}, count = 1; ENTRY; - rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); - if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) { - CERROR("mds: out of memory\n"); - req->rq_status = -ENOMEM; - RETURN(0); - } - body = lustre_msg_buf(req->rq_reqmsg, 0); de = mds_fid2dentry(mds, &body->fid1, NULL); if (IS_ERR(de)) { req->rq_status = -ENOENT; RETURN(0); } + inode = de->d_inode; + if (body->valid & OBD_MD_LINKNAME) { + count = 2; + size[1] = inode->i_size; + } + + rc = lustre_pack_msg(count, size, NULL, &req->rq_replen, + &req->rq_repmsg); + if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) { + CERROR("mds: out of memory\n"); + req->rq_status = -ENOMEM; + GOTO(out, 0); + } + + if (body->valid & OBD_MD_LINKNAME) { + char *tmp = lustre_msg_buf(req->rq_repmsg, 1); + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + rc = inode->i_op->readlink(de, tmp, size[1]); + set_fs(oldfs); + + if (rc < 0) { + req->rq_status = rc; + CERROR("readlink failed: %d\n", req->rq_status); + GOTO(out, 0); + } + } body = lustre_msg_buf(req->rq_repmsg, 0); - inode = de->d_inode; body->ino = inode->i_ino; body->generation = inode->i_generation; body->atime = inode->i_atime; @@ -333,6 +353,7 @@ int mds_getattr(struct ptlrpc_request *req) body->nlink = inode->i_nlink; body->valid = ~0; mds_fs_get_objid(mds, inode, &body->objid); + out: l_dput(de); RETURN(0); } diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c index b9b842d..fb15f2a 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -259,10 +259,9 @@ static int ptlrpc_check_reply(struct ptlrpc_request *req) if (req->rq_client && req->rq_client->cli_recovd) recovd_cli_fail(req->rq_client); if (req->rq_level < LUSTRE_CONN_FULL) - rc = -ETIMEDOUT; - else + rc = 1; + else rc = 0; - GOTO(out, rc); } @@ -489,15 +488,17 @@ int ptlrpc_queue_wait(struct ptlrpc_request *req) } up(&cli->cli_rpc_sem); + if (req->rq_flags & PTL_RPC_FL_TIMEOUT) + GOTO(out, rc = -ETIMEDOUT); + if (req->rq_flags & PTL_RPC_FL_INTR) { /* Clean up the dangling reply buffers */ ptlrpc_abort(req); GOTO(out, rc = -EINTR); } - if (! (req->rq_flags & PTL_RPC_FL_REPLIED)) { + if (!(req->rq_flags & PTL_RPC_FL_REPLIED)) GOTO(out, rc = req->rq_status); - } rc = lustre_unpack_msg(req->rq_repmsg, req->rq_replen); if (rc) { -- 1.8.3.1