Whamcloud - gitweb
- Fixed symlinks
authorpschwan <pschwan>
Thu, 23 May 2002 20:52:49 +0000 (20:52 +0000)
committerpschwan <pschwan>
Thu, 23 May 2002 20:52:49 +0000 (20:52 +0000)
- Fixed connect-failure-leads-to-segfault bug

lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_mds.h
lustre/llite/namei.c
lustre/llite/super.c
lustre/llite/symlink.c
lustre/mdc/mdc_request.c
lustre/mds/handler.c
lustre/ptlrpc/client.c

index a6783e9..f17fef2 100644 (file)
@@ -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 */
 
index 4395900..c1b3b55 100644 (file)
@@ -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,
index 095f0e5..16d4a0e 100644 (file)
@@ -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);
index 9735456..000502a 100644 (file)
@@ -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);
index 5f54913..ab87a92 100644 (file)
 #include <linux/obd_support.h> /* for ENTRY and EXIT only */
 #include <linux/lustre_lite.h>
 
-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
 };
-
index 0e906a4..4be6294 100644 (file)
@@ -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);
index e22bbee..0ce5167 100644 (file)
@@ -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);
 }
index b9b842d..fb15f2a 100644 (file)
@@ -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) {