#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 */
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,
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);
/* 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);
#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
};
-
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);
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);
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);
(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);
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;
body->nlink = inode->i_nlink;
body->valid = ~0;
mds_fs_get_objid(mds, inode, &body->objid);
+ out:
l_dput(de);
RETURN(0);
}
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);
}
}
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) {