*
* Copyright (C) 2001, 2002 Cluster File Systems, Inc.
*
- * This file is part of Portals, http://www.sf.net/projects/lustre/
+ * This file is part of Lustre, http://www.sf.net/projects/lustre/
*
- * Portals is free software; you can redistribute it and/or
+ * Lustre is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
- * Portals is distributed in the hope that it will be useful,
+ * Lustre is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with Portals; if not, write to the Free Software
+ * along with Lustre; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/errno.h>
-#include <linux/locks.h>
-#include <linux/unistd.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <asm/uaccess.h>
-#include <asm/segment.h>
-#include <linux/miscdevice.h>
#define DEBUG_SUBSYSTEM S_MDC
-#include <linux/obd_support.h>
#include <linux/obd_class.h>
-#include <linux/lustre_lib.h>
-#include <linux/lustre_idl.h>
#include <linux/lustre_mds.h>
+#include <linux/obd_lov.h>
-extern int mdc_reint(struct ptlrpc_client *peer, struct ptlrpc_request *request);
-
-int mdc_setattr(struct ptlrpc_client *peer,
- struct inode *inode, struct iattr *iattr,
- struct ptlrpc_request **request)
+static int mdc_reint(struct ptlrpc_request *request, int level)
{
- int rc;
- struct mds_rec_setattr *rec;
- ENTRY;
+ int rc;
+ request->rq_level = level;
- *request = ptlrpc_prep_req(peer, MDS_REINT, 0, NULL, sizeof(*rec), NULL);
- if (!(*request)) {
- CERROR("mdc request: cannot pack\n");
- return -ENOMEM;
- }
+ rc = ptlrpc_queue_wait(request);
+ rc = ptlrpc_check_status(request, rc);
- rec = mds_req_tgt((*request)->rq_req.mds);
- mds_setattr_pack(rec, inode, iattr);
- (*request)->rq_req.mds->opcode = HTON__u32(REINT_SETATTR);
- (*request)->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
+ if (rc)
+ CERROR("error in handling %d\n", rc);
- rc = mdc_reint(peer, *request);
-
- EXIT;
return rc;
}
-int mdc_create(struct ptlrpc_client *peer,
- struct inode *dir, const char *name, int namelen,
- const char *tgt, int tgtlen,
- int mode, __u64 id, __u32 uid, __u32 gid, __u64 time,
- struct ptlrpc_request **request)
+int mdc_setattr(struct lustre_handle *conn,
+ struct inode *inode, struct iattr *iattr,
+ struct ptlrpc_request **request)
{
- int rc;
- struct mds_rec_create *rec;
+ struct ptlrpc_request *req;
+ struct mds_rec_setattr *rec;
+ int rc, size = sizeof(*rec);
ENTRY;
- (*request) = ptlrpc_prep_req(peer, MDS_REINT, 0, NULL,
- sizeof(*rec) + size_round0(namelen) +
- size_round0(tgtlen), NULL);
- if (!(*request)) {
- CERROR("mdc_create: cannot pack\n");
- return -ENOMEM;
- }
+ req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 1, &size,
+ NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ mds_setattr_pack(req, 0, inode, iattr, NULL, 0);
- (*request)->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
+ size = sizeof(struct mds_body);
+ req->rq_replen = lustre_msg_size(1, &size);
- rec = mds_req_tgt((*request)->rq_req.mds);
- mds_create_pack(rec, dir, name, namelen, mode, id, uid, gid, time,
- tgt, tgtlen);
+ rc = mdc_reint(req, LUSTRE_CONN_FULL);
+ *request = req;
+ if (rc == -ERESTARTSYS )
+ rc = 0;
- rc = mdc_reint(peer, (*request));
+ RETURN(rc);
+}
- EXIT;
- return rc;
+int mdc_create(struct lustre_handle *conn,
+ struct inode *dir, const char *name, int namelen,
+ const char *tgt, int tgtlen, int mode, __u32 uid,
+ __u32 gid, __u64 time, __u64 rdev, struct lov_stripe_md *smd,
+ struct ptlrpc_request **request)
+{
+ struct mds_rec_create *rec;
+ struct ptlrpc_request *req;
+ int rc, size[3] = {sizeof(struct mds_rec_create), namelen + 1, 0};
+ char *tmp;
+ int level, bufcount = 2;
+ ENTRY;
+
+ if (S_ISREG(mode)) {
+ if (!smd) {
+ CERROR("File create, but no md (%ld, %*s)\n",
+ dir->i_ino, namelen, name);
+ LBUG();
+ }
+ size[2] = smd->lmd_easize;
+ bufcount = 3;
+ } else if (S_ISLNK(mode)) {
+ size[2] = tgtlen + 1;
+ bufcount = 3;
+ }
+
+ req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, bufcount, size,
+ NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ /* mds_create_pack fills msg->bufs[1] with name */
+ rec = lustre_msg_buf(req->rq_reqmsg, 0);
+ mds_create_pack(req, 0, dir, mode, rdev, uid, gid, time,
+ name, namelen, NULL, 0);
+
+ if (S_ISREG(mode)) {
+ lov_packmd(lustre_msg_buf(req->rq_reqmsg, 2), smd);
+ } else if (S_ISLNK(mode)) {
+ tmp = lustre_msg_buf(req->rq_reqmsg, 2);
+ LOGL0(tgt, tgtlen, tmp);
+ }
+
+ size[0] = sizeof(struct mds_body);
+ req->rq_replen = lustre_msg_size(1, size);
+
+ level = LUSTRE_CONN_FULL;
+ resend:
+ rc = mdc_reint(req, level);
+ if (rc == -ERESTARTSYS) {
+ __u32 *opcode = lustre_msg_buf(req->rq_reqmsg, 0);
+ level = LUSTRE_CONN_RECOVD;
+ CERROR("Lost reply: re-create rep.\n");
+ req->rq_flags = 0;
+ *opcode = NTOH__u32(REINT_RECREATE);
+ goto resend;
+ }
+
+ *request = req;
+ RETURN(rc);
}
-int mdc_unlink(struct ptlrpc_client *peer,
- struct inode *dir, const char *name, int namelen,
+int mdc_unlink(struct lustre_handle *conn, struct inode *dir,
+ struct inode *child, __u32 mode, const char *name, int namelen,
struct ptlrpc_request **request)
{
- int rc;
- struct mds_rec_unlink *rec;
+ struct ptlrpc_request *req;
+ int rc, size[2] = {sizeof(struct mds_rec_unlink), namelen + 1};
+ ENTRY;
- (*request) = ptlrpc_prep_req(peer, MDS_REINT, 0, NULL,
- sizeof(*rec) + size_round0(namelen), NULL);
- if (!(*request)) {
- CERROR("mdc_unlink: cannot pack\n");
- return -ENOMEM;
- }
+ req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 2, size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
- (*request)->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
+ mds_unlink_pack(req, 0, dir, child, mode, name, namelen);
- rec = mds_req_tgt((*request)->rq_req.mds);
- mds_unlink_pack(rec, dir, name, namelen);
+ size[0] = sizeof(struct mds_body);
+ req->rq_replen = lustre_msg_size(1, size);
- rc = mdc_reint(peer, (*request));
+ rc = mdc_reint(req, LUSTRE_CONN_FULL);
+ *request = req;
+ if (rc == -ERESTARTSYS)
+ rc = 0;
- EXIT;
- return rc;
+ RETURN(rc);
}
-int mdc_link(struct ptlrpc_client *peer, struct dentry *src,
- struct inode *dir, const char *name, int namelen,
- struct ptlrpc_request **request)
+int mdc_link(struct lustre_handle *conn,
+ struct dentry *src, struct inode *dir, const char *name,
+ int namelen, struct ptlrpc_request **request)
{
- int rc;
- struct mds_rec_link *rec;
+ struct ptlrpc_request *req;
+ int rc, size[2] = {sizeof(struct mds_rec_link), namelen + 1};
ENTRY;
- (*request) = ptlrpc_prep_req(peer, MDS_REINT, 0, NULL,
- sizeof(*rec) + size_round0(namelen), NULL);
- if (!(*request)) {
- CERROR("mdc_link: cannot pack\n");
- return -ENOMEM;
- }
+ req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 2, size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
+
+ mds_link_pack(req, 0, src->d_inode, dir, name, namelen);
- (*request)->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
+ size[0] = sizeof(struct mds_body);
+ req->rq_replen = lustre_msg_size(1, size);
- rec = mds_req_tgt((*request)->rq_req.mds);
- mds_link_pack(rec, src->d_inode, dir, name, namelen);
+ rc = mdc_reint(req, LUSTRE_CONN_FULL);
+ *request = req;
+ if (rc == -ERESTARTSYS )
+ rc = 0;
- rc = mdc_reint(peer, (*request));
- EXIT;
- return rc;
+ RETURN(rc);
}
-int mdc_rename(struct ptlrpc_client *peer, struct inode *src,
- struct inode *tgt, const char *old, int oldlen,
- const char *new, int newlen,
+int mdc_rename(struct lustre_handle *conn,
+ struct inode *src, struct inode *tgt, const char *old,
+ int oldlen, const char *new, int newlen,
struct ptlrpc_request **request)
{
- int rc;
- struct mds_rec_rename *rec;
+ struct ptlrpc_request *req;
+ int rc, size[3] = {sizeof(struct mds_rec_rename), oldlen + 1,
+ newlen + 1};
ENTRY;
- (*request) = ptlrpc_prep_req(peer, MDS_REINT, 0, NULL,
- sizeof(*rec) + size_round0(oldlen)
- + size_round0(newlen), NULL);
- if (!(*request)) {
- CERROR("mdc_link: cannot pack\n");
- return -ENOMEM;
- }
+ req = ptlrpc_prep_req(class_conn2cliimp(conn), MDS_REINT, 3, size, NULL);
+ if (!req)
+ RETURN(-ENOMEM);
- (*request)->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
+ mds_rename_pack(req, 0, src, tgt, old, oldlen, new, newlen);
- rec = mds_req_tgt((*request)->rq_req.mds);
- mds_rename_pack(rec, src, tgt, old, oldlen, new, newlen);
+ size[0] = sizeof(struct mds_body);
+ req->rq_replen = lustre_msg_size(1, size);
- rc = mdc_reint(peer, (*request));
+ rc = mdc_reint(req, LUSTRE_CONN_FULL);
+ *request = req;
+ if (rc == -ERESTARTSYS )
+ rc = 0;
- EXIT;
- return rc;
+ RETURN(rc);
}