typedef enum {
ELDLM_OK = 0,
- ELDLM_BLOCK_GRANTED,
+ ELDLM_BLOCK_GRANTED = 600,
ELDLM_BLOCK_CONV,
- ELDLM_BLOCK_WAIT
+ ELDLM_BLOCK_WAIT,
+ ELDLM_BAD_NAMESPACE,
+ ELDLM_RES_CHANGED
} ldlm_error_t;
-/* lock types */
-typedef enum {
- LCK_EX = 1,
- LCK_PW,
- LCK_PR,
- LCK_CW,
- LCK_CR,
- LCK_NL
-} ldlm_mode_t;
+#define LDLM_FL_RES_CHANGED (1 << 0)
+#define LDLM_FL_COMPLETION_AST (1 << 1)
+#define LDLM_FL_BLOCKING_AST (1 << 2)
#define L2B(c) (1 << c)
static inline int lockmode_compat(ldlm_mode_t exist, ldlm_mode_t new)
{
if (exist < LCK_EX || exist > LCK_NL)
- BUG();
+ LBUG();
if (new < LCK_EX || new > LCK_NL)
- BUG();
+ LBUG();
return (lck_compat_array[exist] & L2B(new));
}
#define RES_HASH_SIZE (1UL << RES_HASH_BITS)
#define RES_HASH_MASK (RES_HASH_SIZE - 1)
-#define RES_NAME_SIZE 6
-#define RES_VERSION_SIZE 4
+struct ldlm_lock;
+
+typedef int (*ldlm_lock_callback)(struct ldlm_lock *lock, struct ldlm_lock *new,
+ void *data);
struct ldlm_lock {
struct ldlm_resource *l_resource;
struct list_head l_res_link; /*position in one of three res lists*/
ldlm_mode_t l_req_mode;
ldlm_mode_t l_granted_mode;
- void *l_completion_ast;
- void *l_blocking_ast;
- void *l_event;
+ ldlm_lock_callback l_completion_ast;
+ ldlm_lock_callback l_blocking_ast;
+ struct lustre_peer *l_peer;
+ //void *l_event;
//XXX cluster_host l_holder;
__u32 l_version[RES_VERSION_SIZE];
};
+typedef int (*ldlm_res_compat)(struct ldlm_resource *child,
+ struct ldlm_resource *new);
+typedef int (*ldlm_res_policy)(struct ldlm_resource *parent, __u64 *res_id_in,
+ __u64 *res_id_out, ldlm_mode_t mode, void *data);
+
+#define LDLM_PLAIN 0x0
+#define LDLM_EXTENT 0x1
+#define LDLM_MDSINTENT 0x2
+
+extern ldlm_res_compat ldlm_res_compat_table [];
+extern ldlm_res_policy ldlm_res_policy_table [];
+
struct ldlm_resource {
struct ldlm_namespace *lr_namespace;
struct list_head lr_hash;
atomic_t lr_refcount;
struct ldlm_resource *lr_root;
//XXX cluster_host lr_master;
- __u32 lr_name[RES_NAME_SIZE];
+ __u64 lr_name[RES_NAME_SIZE];
__u32 lr_version[RES_VERSION_SIZE];
+ __u32 lr_type; /* PLAIN, EXTENT, or MDSINTENT */
spinlock_t lr_lock;
void (*lr_blocking)(struct ldlm_lock *lock, struct ldlm_lock *new);
};
-struct ldlm_handle {
- __u64 addr;
- __u64 cookie;
+struct ldlm_extent {
+ __u64 start;
+ __u64 end;
};
+static inline struct ldlm_extent *ldlm_res2extent(struct ldlm_resource *res)
+{
+ return (struct ldlm_extent *)(res->lr_name);
+}
+
+static inline void *ldlm_handle2object(struct ldlm_handle *handle)
+{
+ return (void *)(unsigned long)(handle->addr);
+}
+
+static inline void ldlm_object2handle(void *object, struct ldlm_handle *handle)
+{
+ handle->addr = (__u64)(unsigned long)object;
+}
+
static inline void ldlm_lock(struct obd_device *obddev)
{
spin_lock(&obddev->u.ldlm.ldlm_lock);
extern struct obd_ops ldlm_obd_ops;
+/* ldlm_extent.c */
+int ldlm_extent_compat(struct ldlm_resource *, struct ldlm_resource *);
+int ldlm_extent_policy(struct ldlm_resource *, __u64 *, __u64 *,
+ ldlm_mode_t, void *);
+
/* ldlm_lock.c */
-ldlm_error_t ldlm_local_lock_enqueue(struct obd_device *obbdev, __u32 ns_id,
- struct ldlm_resource *parent_res,
- struct ldlm_lock *parent_lock,
- __u32 *res_id, ldlm_mode_t mode,
- struct ldlm_handle *);
+ldlm_error_t ldlm_local_lock_enqueue(struct obd_device *obddev,
+ __u32 ns_id,
+ struct ldlm_handle *parent_res_handle,
+ struct ldlm_handle *parent_lock_handle,
+ __u64 *res_id,
+ ldlm_mode_t mode,
+ int *flags,
+ ldlm_lock_callback completion,
+ ldlm_lock_callback blocking,
+ __u32 data_len,
+ void *data,
+ struct ldlm_handle *lockh);
void ldlm_lock_dump(struct ldlm_lock *lock);
/* ldlm_test.c */
void ldlm_resource_dump(struct ldlm_resource *res);
struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns,
struct ldlm_resource *parent,
- __u32 *name, int create);
+ __u64 *name, int create);
int ldlm_resource_put(struct ldlm_resource *res);
#endif /* __KERNEL__ */
* this file contains all data structures used in Lustre interfaces:
* - obdo and obd_request records
* - mds_request records
+ * - ldlm data
* - ioctl's
*/
+struct lustre_msg {
+ __u32 opc;
+ __u32 xid;
+ __u32 status;
+ __u32 type;
+ __u32 connid;
+ __u32 bufcount;
+ __u32 buflens[0];
+};
+
+struct ptlreq_hdr {
+ __u32 opc;
+ __u32 xid;
+ __u32 status;
+ __u32 type;
+ __u32 connid;
+ __u32 bufcount;
+ __u32 buflens[0];
+};
+
+struct ptlrep_hdr {
+ __u32 opc;
+ __u32 xid;
+ __u32 status;
+ __u32 type;
+ __u32 connid;
+ __u32 bufcount;
+ __u32 buflens[0];
+};
/*
* OST requests: OBDO & OBD request records
#define OST_OPEN 10
#define OST_CLOSE 11
-/* packet types */
-#define OST_TYPE_REQ 1
-#define OST_TYPE_REP 2
-#define OST_TYPE_ERR 3
-
-struct ptlreq_hdr {
- __u32 opc;
- __u32 xid;
- __u32 status;
- __u32 type;
-};
-
-struct ptlrep_hdr {
- __u32 opc;
- __u32 xid;
- __u32 status;
- __u32 type;
-};
typedef uint64_t obd_id;
typedef uint64_t obd_gr;
* MDS REQ RECORDS
*/
-
-#define MDS_TYPE_REQ 1
-#define MDS_TYPE_REP 2
-#define MDS_TYPE_ERR 3
-
#define MDS_GETATTR 1
#define MDS_OPEN 2
#define MDS_CLOSE 3
__u32 mode;
__u32 uid;
__u32 gid;
+ __u64 objid;
__u64 size;
__u32 mtime;
__u32 ctime;
__u32 ino;
__u32 nlink;
__u32 generation;
- __u64 objid;
};
struct mds_rep {
__u32 mode;
__u32 uid;
__u32 gid;
+ __u64 objid;
__u64 size;
__u32 mtime;
__u32 ctime;
__u32 ino;
__u32 nlink;
__u32 generation;
- __u64 objid;
};
/* MDS update records */
static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode)
{
- fid->id = HTON__u64((__u64)inode->i_ino);
- fid->generation = HTON__u32(inode->i_generation);
- fid->f_type = HTON__u32(inode->i_mode & S_IFMT);
+ ll_ino2fid(fid, inode->i_ino, inode->i_generation, inode->i_mode &S_IFMT);
}
#endif
/*
+ * LDLM requests:
+ */
+
+/* opcodes */
+#define LDLM_ENQUEUE 1
+#define LDLM_CONVERT 2
+#define LDLM_CANCEL 3
+#define LDLM_CALLBACK 4
+
+#define RES_NAME_SIZE 3
+#define RES_VERSION_SIZE 4
+
+/* lock types */
+typedef enum {
+ LCK_EX = 1,
+ LCK_PW,
+ LCK_PR,
+ LCK_CW,
+ LCK_CR,
+ LCK_NL
+} ldlm_mode_t;
+
+struct ldlm_handle {
+ __u64 addr;
+ __u64 cookie;
+};
+
+struct ldlm_request {
+ __u32 ns_id;
+ __u64 res_id[RES_NAME_SIZE];
+ __u32 flags;
+ struct ldlm_handle parent_res_handle;
+ struct ldlm_handle parent_lock_handle;
+ ldlm_mode_t mode;
+};
+
+struct ldlm_reply {
+ struct ldlm_handle lock_handle;
+};
+
+/*
* OBD IOCTLS
*/
union ptl_rep {
struct mds_rep *mds;
struct ost_rep *ost;
+ struct lustre_msg *lustre;
};
union ptl_req {
struct mds_req *mds;
struct ost_req *ost;
+ struct lustre_msg *lustre;
};
#endif
#define MDS_REPLY_PORTAL 11
#define MDS_BULK_PORTAL 12
+#define LDLM_REQUEST_PORTAL 13
+#define LDLM_REPLY_PORTAL 14
+
/* default rpc ring length */
#define RPC_RING_LENGTH 2
#define PTL_RPC_BULK 4
#define PTL_RPC_SENT 5
#define PTL_BULK_SENT 6
-#define PTL_BULK_RCVD 6
+#define PTL_BULK_RCVD 7
+#define PTL_RPC_ERR 8
struct ptlrpc_request {
int rq_type; /* one of PTL_RPC_REQUEST, PTL_RPC_REPLY, PTL_RPC_BULK */
/* rpc/service.c */
struct ptlrpc_service *
ptlrpc_init_svc(__u32 bufsize, int req_portal, int rep_portal, char *uuid,
- req_unpack_t unpack, rep_pack_t pack, svc_handler_t);
+ svc_handler_t);
void ptlrpc_stop_thread(struct ptlrpc_service *svc);
int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc,
char *name);
};
struct ldlm_obd {
+ struct ptlrpc_service *ldlm_service;
+
struct list_head ldlm_namespaces;
spinlock_t ldlm_lock;
};
extern void obd_sysctl_init (void);
extern void obd_sysctl_clean (void);
+/* pack_generic.c */
+int lustre_pack_msg(int count, int *lens, char **bufs, int *len, char **buf);
+int lustre_unpack_msg(char *buf, int len);
+void *lustre_msg_buf(int n, struct lustre_msg *m);
+
#endif /* __LINUX_CLASS_OBD_H */
OBD_FAIL_OST_CLOSE_NET,
OBD_FAIL_OST_BRW_NET,
OBD_FAIL_OST_PUNCH_NET,
+
+ OBB_FAIL_LDLM = 0x300,
+ OBD_FAIL_LDLM_ENQUEUE,
+ OBD_FAIL_LDLM_CONVERT,
+ OBD_FAIL_LDLM_CANCEL,
+ OBD_FAIL_LDLM_CALLBACK,
+
};
/* preparation for a more advanced failure testbed (not functional yet) */
modulefs_DATA = ldlm.o
EXTRA_PROGRAMS = ldlm
-ldlm_SOURCES = ldlm_lock.c resource.c ldlm_test.c
+pack_generic.c:
+ ln -s ../lib/pack_generic.c
+ldlm_SOURCES = ldlm_lock.c ldlm_resource.c ldlm_test.c ldlm_lockd.c \
+ldlm_extent.c pack_generic.c
include $(top_srcdir)/Rules
extern kmem_cache_t *ldlm_lock_slab;
+ldlm_res_compat ldlm_res_compat_table [] = {
+ [LDLM_PLAIN] NULL,
+ [LDLM_EXTENT] ldlm_extent_compat,
+ [LDLM_MDSINTENT] NULL
+};
+
+ldlm_res_policy ldlm_res_policy_table [] = {
+ [LDLM_PLAIN] NULL,
+ [LDLM_EXTENT] ldlm_extent_policy,
+ [LDLM_MDSINTENT] NULL
+};
+
static struct ldlm_lock *ldlm_lock_new(struct ldlm_lock *parent,
struct ldlm_resource *resource,
ldlm_mode_t mode)
lock = kmem_cache_alloc(ldlm_lock_slab, SLAB_KERNEL);
if (lock == NULL)
- BUG();
+ return NULL;
memset(lock, 0, sizeof(*lock));
lock->l_resource = resource;
if (pending->l_granted_mode < res->lr_most_restr)
res->lr_most_restr = pending->l_granted_mode;
- /* XXX call completion here */
+ if (pending->l_completion_ast)
+ pending->l_completion_ast(pending, NULL, NULL);
}
return rc;
}
-ldlm_error_t ldlm_local_lock_enqueue(struct obd_device *obddev, __u32 ns_id,
- struct ldlm_resource *parent_res,
- struct ldlm_lock *parent_lock,
- __u32 *res_id, ldlm_mode_t mode,
+ldlm_error_t ldlm_local_lock_enqueue(struct obd_device *obddev,
+ __u32 ns_id,
+ struct ldlm_handle *parent_res_handle,
+ struct ldlm_handle *parent_lock_handle,
+ __u64 *res_id,
+ ldlm_mode_t mode,
+ int *flags,
+ ldlm_lock_callback completion,
+ ldlm_lock_callback blocking,
+ __u32 data_len,
+ void *data,
struct ldlm_handle *lockh)
{
struct ldlm_namespace *ns;
- struct ldlm_resource *res;
- struct ldlm_lock *lock;
- int incompat, rc;
+ struct ldlm_resource *res, *parent_res;
+ struct ldlm_lock *lock, *parent_lock;
+ int incompat = 0, rc;
+ __u64 new_id[RES_NAME_SIZE];
+ ldlm_res_compat compat;
+ ldlm_res_policy policy;
ENTRY;
- ns = ldlm_namespace_find(obddev, ns_id);
- if (ns == NULL || ns->ns_hash == NULL)
- BUG();
+ parent_res = ldlm_handle2object(parent_res_handle);
+ parent_lock = ldlm_handle2object(parent_lock_handle);
+
+ ns = ldlm_namespace_find(obddev, ns_id);
+ if (ns == NULL || ns->ns_hash == NULL)
+ RETURN(-ELDLM_BAD_NAMESPACE);
+
+ if (parent_res &&
+ (policy = ldlm_res_policy_table[parent_res->lr_type])) {
+ rc = policy(parent_res, res_id, new_id, mode, NULL);
+ if (rc == ELDLM_RES_CHANGED) {
+ *flags |= LDLM_FL_RES_CHANGED;
+ memcpy(res_id, new_id, sizeof(__u64) * RES_NAME_SIZE);
+ }
+ }
res = ldlm_resource_get(ns, parent_res, res_id, 1);
if (res == NULL)
- BUG();
+ RETURN(-ENOMEM);
lock = ldlm_lock_new(parent_lock, res, mode);
if (lock == NULL)
- BUG();
+ RETURN(-ENOMEM);
- lockh->addr = (__u64)(unsigned long)lock;
+ if ((*flags) & LDLM_FL_COMPLETION_AST)
+ lock->l_completion_ast = completion;
+ if ((*flags) & LDLM_FL_BLOCKING_AST)
+ lock->l_blocking_ast = blocking;
+ ldlm_object2handle(lock, lockh);
spin_lock(&res->lr_lock);
/* FIXME: We may want to optimize by checking lr_most_restr */
if (!list_empty(&res->lr_converting)) {
list_add(&lock->l_res_link, res->lr_waiting.prev);
- rc = ELDLM_BLOCK_CONV;
+ rc = -ELDLM_BLOCK_CONV;
GOTO(out, rc);
}
if (!list_empty(&res->lr_waiting)) {
list_add(&lock->l_res_link, res->lr_waiting.prev);
- rc = ELDLM_BLOCK_WAIT;
+ rc = -ELDLM_BLOCK_WAIT;
GOTO(out, rc);
}
- incompat = ldlm_notify_incompatible(&res->lr_granted, lock);
+
+ if (parent_res &&
+ (compat = ldlm_res_compat_table[parent_res->lr_type])) {
+ struct list_head *tmp;
+ list_for_each(tmp, &parent_res->lr_children) {
+ struct ldlm_resource *child;
+ child = list_entry(tmp, struct ldlm_resource,
+ lr_childof);
+
+ if (compat(child, res))
+ continue;
+
+ incompat |= ldlm_notify_incompatible(&child->lr_granted,
+ lock);
+ }
+ } else
+ incompat = ldlm_notify_incompatible(&res->lr_granted, lock);
+
if (incompat) {
list_add(&lock->l_res_link, res->lr_waiting.prev);
- rc = ELDLM_BLOCK_GRANTED;
+ rc = -ELDLM_BLOCK_GRANTED;
GOTO(out, rc);
}
if (mode < res->lr_most_restr)
res->lr_most_restr = mode;
- /* XXX call the completion call back function */
+ if (lock->l_completion_ast)
+ lock->l_completion_ast(lock, NULL, NULL);
rc = ELDLM_OK;
GOTO(out, rc);
return 0;
}
+ldlm_error_t ldlm_local_lock_convert(struct obd_device *obddev,
+ struct ldlm_handle *lockh,
+ int new_mode, int flags)
+{
+ struct ldlm_lock *lock;
+ struct ldlm_resource *res = lock->l_resource;
+ ENTRY;
+
+ lock = (struct ldlm_lock *)(unsigned long)lockh->addr;
+ list_del(&lock->l_res_link);
+ lock->l_req_mode = new_mode;
+
+ list_add(&lock->l_res_link, &lock->l_resource->lr_converting);
+
+ ldlm_reprocess_queue(&res->lr_converting, &res->lr_granted);
+ if (list_empty(&res->lr_converting))
+ ldlm_reprocess_queue(&res->lr_waiting, &res->lr_granted);
+
+ return 0;
+}
+
void ldlm_lock_dump(struct ldlm_lock *lock)
{
char ver[128];
if (RES_VERSION_SIZE != 4)
- BUG();
+ LBUG();
snprintf(ver, sizeof(ver), "%x %x %x %x",
lock->l_version[0], lock->l_version[1],
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2002 Cluster File Systems, Inc.
+ *
+ * This code is issued under the GNU General Public License.
+ * See the file COPYING in this distribution
+ *
+ * by Cluster File Systems, Inc.
+ */
+
+#define EXPORT_SYMTAB
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/unistd.h>
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+#include <linux/obd_class.h>
+#include <linux/lustre_dlm.h>
+#include <linux/lustre_net.h>
+
+extern kmem_cache_t *ldlm_resource_slab;
+extern kmem_cache_t *ldlm_lock_slab;
+
+static int ldlm_client_callback(struct ldlm_lock *lock, struct ldlm_lock *new,
+ void *data)
+{
+ LBUG();
+ return 0;
+}
+
+static int ldlm_enqueue(struct ptlrpc_request *req)
+{
+ struct ldlm_reply *dlm_rep;
+ struct ldlm_request *dlm_req;
+ struct lustre_msg *msg, *req_msg;
+ ldlm_error_t err;
+ int rc;
+ int bufsize = sizeof(*dlm_rep);
+
+ rc = lustre_pack_msg(1, &bufsize, NULL, &req->rq_replen,
+ &req->rq_repbuf);
+ if (rc) {
+ CERROR("out of memory\n");
+ req->rq_status = -ENOMEM;
+ RETURN(0);
+ }
+ msg = (struct lustre_msg *)req->rq_repbuf;
+ req_msg = req->rq_req.lustre;
+ dlm_rep = lustre_msg_buf(0, msg);
+ dlm_req = lustre_msg_buf(0, req_msg);
+
+ msg->xid = req_msg->xid;
+
+ err = ldlm_local_lock_enqueue(req->rq_obd, dlm_req->ns_id,
+ &dlm_req->parent_res_handle,
+ &dlm_req->parent_lock_handle,
+ dlm_req->res_id, dlm_req->mode,
+ &dlm_req->flags, ldlm_client_callback,
+ ldlm_client_callback,
+ req_msg->buflens[1],
+ lustre_msg_buf(1, req_msg),
+ &dlm_rep->lock_handle);
+ msg->status = HTON__u32(err);
+
+ /* XXX unfinished */
+ return 0;
+}
+
+static int ldlm_handle(struct obd_device *dev, struct ptlrpc_service *svc,
+ struct ptlrpc_request *req)
+{
+ int rc;
+ struct ptlreq_hdr *hdr;
+
+ ENTRY;
+
+ hdr = (struct ptlreq_hdr *)req->rq_reqbuf;
+
+ if (NTOH__u32(hdr->type) != PTL_RPC_REQUEST) {
+ CERROR("lustre_ldlm: wrong packet type sent %d\n",
+ NTOH__u32(hdr->type));
+ rc = -EINVAL;
+ GOTO(out, rc);
+ }
+
+ rc = lustre_unpack_msg(req->rq_reqbuf, req->rq_reqlen);
+ req->rq_reqhdr = (void *)req->rq_reqbuf;
+ if (rc) {
+ CERROR("lustre_ldlm: Invalid request\n");
+ GOTO(out, rc);
+ }
+
+ switch (req->rq_reqhdr->opc) {
+ case LDLM_ENQUEUE:
+ CDEBUG(D_INODE, "enqueue\n");
+ OBD_FAIL_RETURN(req, OBD_FAIL_LDLM_ENQUEUE);
+ rc = ldlm_enqueue(req);
+ break;
+#if 0
+ case LDLM_CONVERT:
+ CDEBUG(D_INODE, "convert\n");
+ OBD_FAIL_RETURN(req, OBD_FAIL_LDLM_CONVERT);
+ rc = ldlm_convert(req);
+ break;
+
+ case LDLM_CANCEL:
+ CDEBUG(D_INODE, "cancel\n");
+ OBD_FAIL_RETURN(req, OBD_FAIL_LDLM_CANCEL);
+ rc = ldlm_cancel(req);
+ break;
+
+ case LDLM_CALLBACK:
+ CDEBUG(D_INODE, "callback\n");
+ OBD_FAIL_RETURN(req, OBD_FAIL_LDLM_CALLBACK);
+ rc = ldlm_callback(req);
+ break;
+#endif
+
+ default:
+ rc = ptlrpc_error(dev, svc, req);
+ RETURN(rc);
+ }
+
+ EXIT;
+out:
+ if (rc) {
+ CERROR("no header\n");
+ return 0;
+ }
+
+ if( req->rq_status) {
+ ptlrpc_error(dev, svc, req);
+ } else {
+ CDEBUG(D_NET, "sending reply\n");
+ ptlrpc_reply(dev, svc, req);
+ }
+
+ return 0;
+}
+
+
+
+static int ldlm_iocontrol(int cmd, struct obd_conn *conn, int len, void *karg,
+ void *uarg)
+{
+ struct obd_device *obddev = conn->oc_dev;
+ int err;
+
+ ENTRY;
+
+ if ( _IOC_TYPE(cmd) != IOC_LDLM_TYPE ||
+ _IOC_NR(cmd) < IOC_LDLM_MIN_NR ||
+ _IOC_NR(cmd) > IOC_LDLM_MAX_NR ) {
+ CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
+ _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
+ EXIT;
+ return -EINVAL;
+ }
+
+ switch (cmd) {
+ case IOC_LDLM_TEST: {
+ err = ldlm_test(obddev);
+ CERROR("-- done err %d\n", err);
+ EXIT;
+ break;
+ }
+ default:
+ err = -EINVAL;
+ EXIT;
+ break;
+ }
+
+ return err;
+}
+
+static int ldlm_setup(struct obd_device *obddev, obd_count len, void *data)
+{
+ struct ldlm_obd *ldlm = &obddev->u.ldlm;
+ int err;
+ ENTRY;
+
+ INIT_LIST_HEAD(&obddev->u.ldlm.ldlm_namespaces);
+ obddev->u.ldlm.ldlm_lock = SPIN_LOCK_UNLOCKED;
+
+ ldlm->ldlm_service = ptlrpc_init_svc(64 * 1024,
+ LDLM_REQUEST_PORTAL,
+ LDLM_REPLY_PORTAL,
+ "self", ldlm_handle);
+
+ rpc_register_service(ldlm->ldlm_service, "self");
+
+ err = ptlrpc_start_thread(obddev, ldlm->ldlm_service, "lustre_dlm");
+ if (err)
+ CERROR("cannot start thread\n");
+
+ MOD_INC_USE_COUNT;
+ RETURN(0);
+}
+
+static int ldlm_cleanup(struct obd_device *obddev)
+{
+ struct ldlm_obd *ldlm = &obddev->u.ldlm;
+ ENTRY;
+
+ ptlrpc_stop_thread(ldlm->ldlm_service);
+ rpc_unregister_service(ldlm->ldlm_service);
+
+ if (!list_empty(&ldlm->ldlm_service->srv_reqs)) {
+ // XXX reply with errors and clean up
+ CERROR("Request list not empty!\n");
+ }
+
+ rpc_unregister_service(ldlm->ldlm_service);
+ OBD_FREE(ldlm->ldlm_service, sizeof(*ldlm->ldlm_service));
+
+ MOD_DEC_USE_COUNT;
+ RETURN(0);
+}
+
+struct obd_ops ldlm_obd_ops = {
+ o_iocontrol: ldlm_iocontrol,
+ o_setup: ldlm_setup,
+ o_cleanup: ldlm_cleanup,
+ o_connect: gen_connect,
+ o_disconnect: gen_disconnect
+};
+
+
+static int __init ldlm_init(void)
+{
+ int rc = obd_register_type(&ldlm_obd_ops, OBD_LDLM_DEVICENAME);
+ if (rc != 0)
+ return rc;
+
+ ldlm_resource_slab = kmem_cache_create("ldlm_resources",
+ sizeof(struct ldlm_resource), 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (ldlm_resource_slab == NULL)
+ return -ENOMEM;
+
+ ldlm_lock_slab = kmem_cache_create("ldlm_locks",
+ sizeof(struct ldlm_lock), 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (ldlm_lock_slab == NULL) {
+ kmem_cache_destroy(ldlm_resource_slab);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void __exit ldlm_exit(void)
+{
+ obd_unregister_type(OBD_LDLM_DEVICENAME);
+ kmem_cache_destroy(ldlm_resource_slab);
+ kmem_cache_destroy(ldlm_lock_slab);
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <braam@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre Lock Management Module v0.1");
+MODULE_LICENSE("GPL");
+
+module_init(ldlm_init);
+module_exit(ldlm_exit);
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2002 Cluster File Systems, Inc.
+ *
+ * This code is issued under the GNU General Public License.
+ * See the file COPYING in this distribution
+ *
+ * by Cluster File Systems, Inc.
+ */
+
+#define EXPORT_SYMTAB
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/unistd.h>
+
+#define DEBUG_SUBSYSTEM S_LDLM
+
+#include <linux/obd_support.h>
+#include <linux/obd_class.h>
+
+#include <linux/lustre_dlm.h>
+
+kmem_cache_t *ldlm_resource_slab;
+kmem_cache_t *ldlm_lock_slab;
+
+struct ldlm_namespace *ldlm_namespace_find(struct obd_device *obddev, __u32 id)
+{
+ struct list_head *tmp;
+ struct ldlm_namespace *res;
+
+ ldlm_lock(obddev);
+
+ res = NULL;
+ list_for_each(tmp, &obddev->u.ldlm.ldlm_namespaces) {
+ struct ldlm_namespace *chk;
+ chk = list_entry(tmp, struct ldlm_namespace, ns_link);
+
+ if ( chk->ns_id == id ) {
+ res = chk;
+ break;
+ }
+ }
+
+ ldlm_unlock(obddev);
+
+ return res;
+}
+
+/* this must be called with ldlm_lock(obddev) held */
+static void res_hash_init(struct ldlm_namespace *ns)
+{
+ struct list_head *res_hash;
+ struct list_head *bucket;
+
+ if (ns->ns_hash != NULL)
+ return;
+
+ OBD_ALLOC(res_hash, sizeof(struct list_head) * RES_HASH_SIZE);
+ if (!res_hash)
+ LBUG();
+
+ for (bucket = res_hash + RES_HASH_SIZE-1 ; bucket >= res_hash ;
+ bucket--) {
+ INIT_LIST_HEAD(bucket);
+ }
+
+ ns->ns_hash = res_hash;
+}
+
+struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obddev, __u32 id)
+{
+ struct ldlm_namespace *ns;
+
+ ldlm_lock(obddev);
+
+ if (ldlm_namespace_find(obddev, id))
+ LBUG();
+
+ OBD_ALLOC(ns, sizeof(*ns));
+ if (!ns)
+ LBUG();
+
+ ns->ns_id = id;
+ INIT_LIST_HEAD(&ns->ns_root_list);
+
+ list_add(&ns->ns_link, &obddev->u.ldlm.ldlm_namespaces);
+
+ res_hash_init(ns);
+
+ ldlm_unlock(obddev);
+
+ return ns;
+}
+
+static __u32 ldlm_hash_fn(struct ldlm_resource *parent, __u64 *name)
+{
+ __u32 hash = 0;
+ int i;
+
+ for (i = 0; i < RES_NAME_SIZE; i++) {
+ hash += name[i];
+ }
+
+ hash += (__u32)((unsigned long)parent >> 4);
+
+ return (hash & RES_HASH_MASK);
+}
+
+static struct ldlm_resource *ldlm_resource_new(void)
+{
+ struct ldlm_resource *res;
+
+ res = kmem_cache_alloc(ldlm_resource_slab, SLAB_KERNEL);
+ if (res == NULL)
+ LBUG();
+ memset(res, 0, sizeof(*res));
+
+ INIT_LIST_HEAD(&res->lr_children);
+ INIT_LIST_HEAD(&res->lr_granted);
+ INIT_LIST_HEAD(&res->lr_converting);
+ INIT_LIST_HEAD(&res->lr_waiting);
+
+ res->lr_lock = SPIN_LOCK_UNLOCKED;
+
+ atomic_set(&res->lr_refcount, 1);
+
+ return res;
+}
+
+/* ldlm_lock(obddev) must be taken before calling resource_add */
+static struct ldlm_resource *ldlm_resource_add(struct ldlm_namespace *ns,
+ struct ldlm_resource *parent,
+ __u64 *name)
+{
+ struct list_head *bucket;
+ struct ldlm_resource *res;
+
+ bucket = ns->ns_hash + ldlm_hash_fn(parent, name);
+
+ res = ldlm_resource_new();
+ if (!res)
+ LBUG();
+
+ memcpy(res->lr_name, name, RES_NAME_SIZE * sizeof(__u32));
+ res->lr_namespace = ns;
+ list_add(&res->lr_hash, bucket);
+ if (parent == NULL) {
+ res->lr_parent = res;
+ list_add(&res->lr_rootlink, &ns->ns_root_list);
+ } else {
+ res->lr_parent = parent;
+ list_add(&res->lr_childof, &parent->lr_children);
+ }
+
+ return res;
+}
+
+struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns,
+ struct ldlm_resource *parent,
+ __u64 *name, int create)
+{
+ struct list_head *bucket;
+ struct list_head *tmp = bucket;
+ struct ldlm_resource *res;
+
+ ENTRY;
+
+ if (ns->ns_hash == NULL)
+ RETURN(NULL);
+ bucket = ns->ns_hash + ldlm_hash_fn(parent, name);
+
+ ldlm_lock(ns->ns_obddev);
+
+ res = NULL;
+ list_for_each(tmp, bucket) {
+ struct ldlm_resource *chk;
+ chk = list_entry(tmp, struct ldlm_resource, lr_hash);
+
+ if (memcmp(chk->lr_name, name,
+ RES_NAME_SIZE * sizeof(__u32)) == 0) {
+ res = chk;
+ atomic_inc(&res->lr_refcount);
+ break;
+ }
+ }
+
+ if (res == NULL && create)
+ res = ldlm_resource_add(ns, parent, name);
+
+ ldlm_unlock(ns->ns_obddev);
+
+ RETURN(res);
+}
+
+int ldlm_resource_put(struct ldlm_resource *res)
+{
+ int rc = 0;
+ ldlm_lock(res->lr_namespace->ns_obddev);
+
+ if (atomic_dec_and_test(&res->lr_refcount)) {
+ if (!list_empty(&res->lr_granted))
+ LBUG();
+
+ if (!list_empty(&res->lr_converting))
+ LBUG();
+
+ if (!list_empty(&res->lr_waiting))
+ LBUG();
+
+ list_del(&res->lr_hash);
+ list_del(&res->lr_rootlink);
+ list_del(&res->lr_childof);
+
+ kmem_cache_free(ldlm_resource_slab, res);
+ rc = 1;
+ }
+ ldlm_unlock(res->lr_namespace->ns_obddev);
+ return rc;
+}
+
+int ldlm_get_resource_handle(struct ldlm_resource *res, struct ldlm_handle *h)
+{
+ LBUG();
+ return 0;
+}
+
+void ldlm_resource_dump(struct ldlm_resource *res)
+{
+ struct list_head *tmp;
+ char name[256];
+
+ if (RES_NAME_SIZE != 3)
+ LBUG();
+
+ snprintf(name, sizeof(name), "%Lx %Lx %Lx",
+ res->lr_name[0], res->lr_name[1], res->lr_name[2]);
+
+ CDEBUG(D_OTHER, "--- Resource: %p (%s)\n", res, name);
+ CDEBUG(D_OTHER, "Namespace: %p (%u)\n", res->lr_namespace,
+ res->lr_namespace->ns_id);
+ CDEBUG(D_OTHER, "Parent: %p, root: %p\n", res->lr_parent, res->lr_root);
+
+ CDEBUG(D_OTHER, "Granted locks:\n");
+ list_for_each(tmp, &res->lr_granted) {
+ struct ldlm_lock *lock;
+ lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+ ldlm_lock_dump(lock);
+ }
+
+ CDEBUG(D_OTHER, "Converting locks:\n");
+ list_for_each(tmp, &res->lr_converting) {
+ struct ldlm_lock *lock;
+ lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+ ldlm_lock_dump(lock);
+ }
+
+ CDEBUG(D_OTHER, "Waiting locks:\n");
+ list_for_each(tmp, &res->lr_waiting) {
+ struct ldlm_lock *lock;
+ lock = list_entry(tmp, struct ldlm_lock, l_res_link);
+ ldlm_lock_dump(lock);
+ }
+}
+
{
struct ldlm_namespace *ns;
struct ldlm_resource *res;
- __u32 res_id[RES_NAME_SIZE] = {1, 2, 3, 4, 5, 6};
+ __u64 res_id[RES_NAME_SIZE] = {1, 2, 3};
ldlm_error_t err;
struct ldlm_handle h;
+ int flags;
ns = ldlm_namespace_new(obddev, 1);
if (ns == NULL)
- BUG();
+ LBUG();
res = ldlm_resource_get(ns, NULL, res_id, 1);
if (res == NULL)
- BUG();
+ LBUG();
res->lr_blocking = ldlm_test_callback;
/* Get a couple of read locks */
- err = ldlm_local_lock_enqueue(obddev, 1, NULL, NULL, res_id,
- LCK_CR, &h);
+ err = ldlm_local_lock_enqueue(obddev, 1, NULL, NULL, res_id, LCK_CR,
+ &flags, NULL, NULL, 0, NULL, &h);
if (err != ELDLM_OK)
- BUG();
+ LBUG();
- err = ldlm_local_lock_enqueue(obddev, 1, NULL, NULL, res_id,
- LCK_CR, &h);
+ err = ldlm_local_lock_enqueue(obddev, 1, NULL, NULL, res_id, LCK_CR,
+ &flags, NULL, NULL, 0, NULL, &h);
if (err != ELDLM_OK)
- BUG();
+ LBUG();
ldlm_resource_dump(res);
+++ /dev/null
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (C) 2002 Cluster File Systems, Inc.
- *
- * This code is issued under the GNU General Public License.
- * See the file COPYING in this distribution
- *
- * by Cluster File Systems, Inc.
- */
-
-#define EXPORT_SYMTAB
-
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/unistd.h>
-
-#define DEBUG_SUBSYSTEM S_LDLM
-
-#include <linux/obd_support.h>
-#include <linux/obd_class.h>
-
-#include <linux/lustre_dlm.h>
-
-static kmem_cache_t *ldlm_resource_slab;
-kmem_cache_t *ldlm_lock_slab;
-
-struct ldlm_namespace *ldlm_namespace_find(struct obd_device *obddev, __u32 id)
-{
- struct list_head *tmp;
- struct ldlm_namespace *res;
-
- ldlm_lock(obddev);
-
- res = NULL;
- list_for_each(tmp, &obddev->u.ldlm.ldlm_namespaces) {
- struct ldlm_namespace *chk;
- chk = list_entry(tmp, struct ldlm_namespace, ns_link);
-
- if ( chk->ns_id == id ) {
- res = chk;
- break;
- }
- }
-
- ldlm_unlock(obddev);
-
- return res;
-}
-
-/* this must be called with ldlm_lock(obddev) held */
-static void res_hash_init(struct ldlm_namespace *ns)
-{
- struct list_head *res_hash;
- struct list_head *bucket;
-
- if (ns->ns_hash != NULL)
- return;
-
- OBD_ALLOC(res_hash, sizeof(struct list_head) * RES_HASH_SIZE);
- if (!res_hash)
- BUG();
-
- for (bucket = res_hash + RES_HASH_SIZE-1 ; bucket >= res_hash ;
- bucket--) {
- INIT_LIST_HEAD(bucket);
- }
-
- ns->ns_hash = res_hash;
-}
-
-struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obddev, __u32 id)
-{
- struct ldlm_namespace *ns;
-
- ldlm_lock(obddev);
-
- if (ldlm_namespace_find(obddev, id))
- BUG();
-
- OBD_ALLOC(ns, sizeof(*ns));
- if (!ns)
- BUG();
-
- ns->ns_id = id;
- INIT_LIST_HEAD(&ns->ns_root_list);
-
- list_add(&ns->ns_link, &obddev->u.ldlm.ldlm_namespaces);
-
- res_hash_init(ns);
-
- ldlm_unlock(obddev);
-
- return ns;
-}
-
-static __u32 ldlm_hash_fn(struct ldlm_resource *parent, __u32 *name)
-{
- __u32 hash = 0;
- int i;
-
- for (i = 0; i < RES_NAME_SIZE; i++) {
- hash += name[i];
- }
-
- hash += (__u32)((unsigned long)parent >> 4);
-
- return (hash & RES_HASH_MASK);
-}
-
-static struct ldlm_resource *ldlm_resource_new(void)
-{
- struct ldlm_resource *res;
-
- res = kmem_cache_alloc(ldlm_resource_slab, SLAB_KERNEL);
- if (res == NULL)
- BUG();
- memset(res, 0, sizeof(*res));
-
- INIT_LIST_HEAD(&res->lr_children);
- INIT_LIST_HEAD(&res->lr_granted);
- INIT_LIST_HEAD(&res->lr_converting);
- INIT_LIST_HEAD(&res->lr_waiting);
-
- res->lr_lock = SPIN_LOCK_UNLOCKED;
-
- atomic_set(&res->lr_refcount, 1);
-
- return res;
-}
-
-/* ldlm_lock(obddev) must be taken before calling resource_add */
-static struct ldlm_resource *ldlm_resource_add(struct ldlm_namespace *ns,
- struct ldlm_resource *parent,
- __u32 *name)
-{
- struct list_head *bucket;
- struct ldlm_resource *res;
-
- bucket = ns->ns_hash + ldlm_hash_fn(parent, name);
-
- res = ldlm_resource_new();
- if (!res)
- BUG();
-
- memcpy(res->lr_name, name, RES_NAME_SIZE * sizeof(__u32));
- res->lr_namespace = ns;
- list_add(&res->lr_hash, bucket);
- if (parent == NULL) {
- res->lr_parent = res;
- list_add(&res->lr_rootlink, &ns->ns_root_list);
- } else {
- res->lr_parent = parent;
- list_add(&res->lr_childof, &parent->lr_children);
- }
-
- return res;
-}
-
-struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns,
- struct ldlm_resource *parent,
- __u32 *name, int create)
-{
- struct list_head *bucket;
- struct list_head *tmp = bucket;
- struct ldlm_resource *res;
-
- if (ns->ns_hash == NULL)
- BUG();
- bucket = ns->ns_hash + ldlm_hash_fn(parent, name);
-
- ldlm_lock(ns->ns_obddev);
-
- res = NULL;
- list_for_each(tmp, bucket) {
- struct ldlm_resource *chk;
- chk = list_entry(tmp, struct ldlm_resource, lr_hash);
-
- if (memcmp(chk->lr_name, name,
- RES_NAME_SIZE * sizeof(__u32)) == 0) {
- res = chk;
- atomic_inc(&res->lr_refcount);
- break;
- }
- }
-
- if (res == NULL && create)
- res = ldlm_resource_add(ns, parent, name);
-
- ldlm_unlock(ns->ns_obddev);
-
- return res;
-}
-
-int ldlm_resource_put(struct ldlm_resource *res)
-{
- int rc = 0;
- ldlm_lock(res->lr_namespace->ns_obddev);
-
- if (atomic_dec_and_test(&res->lr_refcount)) {
- if (!list_empty(&res->lr_granted))
- BUG();
-
- if (!list_empty(&res->lr_converting))
- BUG();
-
- if (!list_empty(&res->lr_waiting))
- BUG();
-
- list_del(&res->lr_hash);
- list_del(&res->lr_rootlink);
- list_del(&res->lr_childof);
-
- kmem_cache_free(ldlm_resource_slab, res);
- rc = 1;
- }
- ldlm_unlock(res->lr_namespace->ns_obddev);
- return rc;
-}
-
-int ldlm_get_resource_handle(struct ldlm_resource *res, struct ldlm_handle *h)
-{
- BUG();
- return 0;
-}
-
-void ldlm_resource_dump(struct ldlm_resource *res)
-{
- struct list_head *tmp;
- char name[256];
-
- if (RES_NAME_SIZE != 6)
- BUG();
-
- snprintf(name, sizeof(name), "%x %x %x %x %x %x",
- res->lr_name[0], res->lr_name[1], res->lr_name[2],
- res->lr_name[3], res->lr_name[4], res->lr_name[5]);
-
- CDEBUG(D_OTHER, "--- Resource: %p (%s)\n", res, name);
- CDEBUG(D_OTHER, "Namespace: %p (%u)\n", res->lr_namespace,
- res->lr_namespace->ns_id);
- CDEBUG(D_OTHER, "Parent: %p, root: %p\n", res->lr_parent, res->lr_root);
-
- CDEBUG(D_OTHER, "Granted locks:\n");
- list_for_each(tmp, &res->lr_granted) {
- struct ldlm_lock *lock;
- lock = list_entry(tmp, struct ldlm_lock, l_res_link);
- ldlm_lock_dump(lock);
- }
-
- CDEBUG(D_OTHER, "Converting locks:\n");
- list_for_each(tmp, &res->lr_converting) {
- struct ldlm_lock *lock;
- lock = list_entry(tmp, struct ldlm_lock, l_res_link);
- ldlm_lock_dump(lock);
- }
-
- CDEBUG(D_OTHER, "Waiting locks:\n");
- list_for_each(tmp, &res->lr_waiting) {
- struct ldlm_lock *lock;
- lock = list_entry(tmp, struct ldlm_lock, l_res_link);
- ldlm_lock_dump(lock);
- }
-}
-
-static int ldlm_obd_setup(struct obd_device *obddev, obd_count len, void *data)
-{
- INIT_LIST_HEAD(&obddev->u.ldlm.ldlm_namespaces);
- obddev->u.ldlm.ldlm_lock = SPIN_LOCK_UNLOCKED;
-
- return 0;
-}
-
-static int ldlm_iocontrol(int cmd, struct obd_conn *conn, int len, void *karg,
- void *uarg)
-{
- struct obd_device *obddev = conn->oc_dev;
- int err;
-
- ENTRY;
-
- if ( _IOC_TYPE(cmd) != IOC_LDLM_TYPE ||
- _IOC_NR(cmd) < IOC_LDLM_MIN_NR ||
- _IOC_NR(cmd) > IOC_LDLM_MAX_NR ) {
- CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
- _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
- EXIT;
- return -EINVAL;
- }
-
- switch (cmd) {
- case IOC_LDLM_TEST: {
- err = ldlm_test(obddev);
- CERROR("-- done err %d\n", err);
- EXIT;
- break;
- }
- default:
- err = -EINVAL;
- EXIT;
- break;
- }
-
- return err;
-}
-
-struct obd_ops ldlm_obd_ops = {
- o_iocontrol: ldlm_iocontrol,
- o_setup: ldlm_obd_setup,
- o_connect: gen_connect,
- o_disconnect: gen_disconnect
-};
-
-static int __init ldlm_init(void)
-{
- int rc = obd_register_type(&ldlm_obd_ops, OBD_LDLM_DEVICENAME);
- if (rc != 0)
- return rc;
-
- ldlm_resource_slab = kmem_cache_create("ldlm_resources",
- sizeof(struct ldlm_resource), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- if (ldlm_resource_slab == NULL)
- return -ENOMEM;
-
- ldlm_lock_slab = kmem_cache_create("ldlm_locks",
- sizeof(struct ldlm_lock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- if (ldlm_lock_slab == NULL) {
- kmem_cache_destroy(ldlm_resource_slab);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void __exit ldlm_exit(void)
-{
- obd_unregister_type(OBD_LDLM_DEVICENAME);
- kmem_cache_destroy(ldlm_resource_slab);
- kmem_cache_destroy(ldlm_lock_slab);
-}
-
-MODULE_AUTHOR("Cluster File Systems, Inc. <braam@clusterfs.com>");
-MODULE_DESCRIPTION("Lustre Lock Management Module v0.1");
-MODULE_LICENSE("GPL");
-
-module_init(ldlm_init);
-module_exit(ldlm_exit);
-EXTRA_DIST = mds_pack.c mds_updates.c obd_pack.c page.c
+EXTRA_DIST = mds_pack.c mds_updates.c obd_pack.c page.c pack_generic.c
include $(top_srcdir)/Rules
OBD_ALLOC(*buf, *len);
if (!*buf) {
- EXIT;
- return -ENOMEM;
+ RETURN(-ENOMEM);
}
memset(*buf, 0, *len);
ptr = *buf + sizeof(**hdr) + sizeof(*req);
- (*hdr)->type = MDS_TYPE_REQ;
+ (*hdr)->type = PTL_RPC_REQUEST;
req->namelen = NTOH__u32(namelen);
- if (name) {
- LOGL(name, namelen, ptr);
- }
+ LOGL(name, namelen, ptr);
req->tgtlen = NTOH__u32(tgtlen);
- if (tgt) {
- LOGL(tgt, tgtlen, ptr);
- }
- return 0;
+ LOGL(tgt, tgtlen, ptr);
+
+ RETURN(0);
}
char *name, *tgt;
if (len < sizeof(**hdr) + sizeof(*req)) {
- EXIT;
- return -EINVAL;
+ RETURN(-EINVAL);
}
*hdr = (struct ptlreq_hdr *) (buf);
if (len < sizeof(**hdr) + sizeof(*req) +
size_round(req->namelen) + size_round(req->tgtlen) ) {
- EXIT;
- return -EINVAL;
+ RETURN(-EINVAL);
}
if (req->namelen) {
tgt = NULL;
}
- EXIT;
- return 0;
+ RETURN(0);
}
void *mds_req_tgt(struct mds_req *req)
ptr = *buf + sizeof(**hdr) + sizeof(*rep);
- (*hdr)->type = MDS_TYPE_REP;
+ (*hdr)->type = PTL_RPC_REPLY;
rep->namelen = NTOH__u32(namelen);
if (name) {
#define DEBUG_SUBSYSTEM S_OST
-#include <linux/obd_support.h>
#include <linux/obd_class.h>
#include <linux/obd_ost.h>
-#include <linux/lustre_lib.h>
-#include <linux/lustre_idl.h>
+#include <linux/lustre_net.h>
int ost_pack_req(char *buf1, int buflen1, char *buf2, int buflen2,
struct ptlreq_hdr **hdr, union ptl_req *r,
OBD_ALLOC(*buf, *len);
if (!*buf) {
- EXIT;
- return -ENOMEM;
+ RETURN(-ENOMEM);
}
memset(*buf, 0, *len);
*hdr = (struct ptlreq_hdr *)(*buf);
- req = (struct ost_req *)(*buf + sizeof(**hdr));
+ req = (struct ost_req *)((*buf) + sizeof(**hdr));
r->ost = req;
ptr = *buf + sizeof(**hdr) + sizeof(*req);
- (*hdr)->type = OST_TYPE_REQ;
+ (*hdr)->type = PTL_RPC_REQUEST;
req->buflen1 = HTON__u32(buflen1);
- if (buf1) {
- LOGL(buf1, buflen1, ptr);
- }
+ LOGL(buf1, buflen1, ptr);
req->buflen2 = HTON__u32(buflen2);
- if (buf2) {
- LOGL(buf2, buflen2, ptr);
- }
- return 0;
+ LOGL(buf2, buflen2, ptr);
+
+ RETURN(0);
}
int ost_unpack_req(char *buf, int len,
struct ost_req *req;
if (len < sizeof(**hdr) + sizeof(*req)) {
- EXIT;
- return -EINVAL;
+ RETURN(-EINVAL);
}
*hdr = (struct ptlreq_hdr *) (buf);
if (len < sizeof(**hdr) + sizeof(*req) +
size_round(req->buflen1) + size_round(req->buflen2) ) {
- EXIT;
- return -EINVAL;
+ RETURN(-EINVAL);
}
- EXIT;
- return 0;
+ RETURN(0);
}
*/
static void __set_page_clean(struct page *page)
{
- struct address_space *mapping = page->mapping;
- struct inode *inode;
-
- if (!mapping)
- return;
+ struct address_space *mapping = page->mapping;
+ struct inode *inode;
+
+ if (!mapping)
+ return;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,9))
- spin_lock(&pagecache_lock);
+ spin_lock(&pagecache_lock);
#endif
- list_del(&page->list);
- list_add(&page->list, &mapping->clean_pages);
+ list_del(&page->list);
+ list_add(&page->list, &mapping->clean_pages);
- inode = mapping->host;
- if (list_empty(&mapping->dirty_pages)) {
- CDEBUG(D_INODE, "inode clean\n");
- inode->i_state &= ~I_DIRTY_PAGES;
- }
+ inode = mapping->host;
+ if (list_empty(&mapping->dirty_pages)) {
+ CDEBUG(D_INODE, "inode clean\n");
+ inode->i_state &= ~I_DIRTY_PAGES;
+ }
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,10))
- spin_unlock(&pagecache_lock);
+ spin_unlock(&pagecache_lock);
#endif
- EXIT;
+ EXIT;
}
inline void set_page_clean(struct page *page)
{
- if (PageDirty(page)) {
- ClearPageDirty(page);
- __set_page_clean(page);
- }
+ if (PageDirty(page)) {
+ ClearPageDirty(page);
+ __set_page_clean(page);
+ }
}
inline void lustre_put_page(struct page *page)
{
- kunmap(page);
- page_cache_release(page);
+ kunmap(page);
+ page_cache_release(page);
}
struct page * lustre_get_page(struct inode *inode, unsigned long n)
{
- struct address_space *mapping = inode->i_mapping;
- struct page *page = read_cache_page(mapping, n,
- (filler_t*)mapping->a_ops->readpage, NULL);
- if (!IS_ERR(page)) {
- wait_on_page(page);
- kmap(page);
- if (!Page_Uptodate(page))
- goto fail;
- if (PageError(page))
- goto fail;
- }
- return page;
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page = read_cache_page(mapping, n,
+ (filler_t*)mapping->a_ops->readpage, NULL);
+ if (!IS_ERR(page)) {
+ wait_on_page(page);
+ kmap(page);
+ if (!Page_Uptodate(page))
+ goto fail;
+ if (PageError(page))
+ goto fail;
+ }
+ return page;
fail:
- lustre_put_page(page);
- return ERR_PTR(-EIO);
+ lustre_put_page(page);
+ return ERR_PTR(-EIO);
}
int lustre_prepare_page(unsigned from, unsigned to, struct page *page)
{
- int err;
+ int err;
- lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ lock_page(page);
+ err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
if (err) {
UnlockPage(page);
CERROR("page index %ld from %d to %d err %d\n",
page->index, from, to, err);
- BUG();
+ LBUG();
}
return err;
}
int lustre_commit_page(struct page *page, unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
- int err = 0;
+ int err = 0;
- SetPageUptodate(page);
- set_page_clean(page);
+ SetPageUptodate(page);
+ set_page_clean(page);
- page->mapping->a_ops->commit_write(NULL, page, from, to);
+ page->mapping->a_ops->commit_write(NULL, page, from, to);
if (IS_SYNC(inode))
- err = waitfor_one_page(page);
- UnlockPage(page);
- lustre_put_page(page);
- return err;
+ err = waitfor_one_page(page);
+ UnlockPage(page);
+ lustre_put_page(page);
+ return err;
}
static int ll_dir_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
{
- return 0;
+ return 0;
}
/* returns the page unlocked, but with a reference */
static int ll_dir_readpage(struct file *file, struct page *page)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = page->mapping->host;
struct ll_sb_info *sbi = ll_i2sbi(inode);
- char *buf;
- __u64 offset;
+ char *buf;
+ __u64 offset;
int rc = 0;
- struct ptlrpc_request *request;
+ struct ptlrpc_request *request;
ENTRY;
- if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT)
+ if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT)
<= page->index) {
- memset(kmap(page), 0, PAGE_CACHE_SIZE);
- kunmap(page);
+ memset(kmap(page), 0, PAGE_CACHE_SIZE);
+ kunmap(page);
EXIT;
- goto readpage_out;
- }
+ goto readpage_out;
+ }
- if (Page_Uptodate(page)) {
+ if (Page_Uptodate(page)) {
CERROR("Explain this please?\n");
- EXIT;
- goto readpage_out;
- }
+ EXIT;
+ goto readpage_out;
+ }
- offset = page->index << PAGE_SHIFT;
- buf = kmap(page);
+ offset = page->index << PAGE_SHIFT;
+ buf = kmap(page);
rc = mdc_readpage(&sbi->ll_mds_client, inode->i_ino, S_IFDIR, offset,
- buf, &request);
- kunmap(page);
+ buf, &request);
+ kunmap(page);
ptlrpc_free_req(request);
EXIT;
if ( !rc )
SetPageUptodate(page);
- UnlockPage(page);
+ UnlockPage(page);
return rc;
} /* ll_dir_readpage */
int waitfor_one_page(struct page *page)
{
- int error = 0;
- struct buffer_head *bh, *head = page->buffers;
-
- bh = head;
- do {
- wait_on_buffer(bh);
- if (buffer_req(bh) && !buffer_uptodate(bh))
- error = -EIO;
- } while ((bh = bh->b_this_page) != head);
- return error;
+ int error = 0;
+ struct buffer_head *bh, *head = page->buffers;
+
+ bh = head;
+ do {
+ wait_on_buffer(bh);
+ if (buffer_req(bh) && !buffer_uptodate(bh))
+ error = -EIO;
+ } while ((bh = bh->b_this_page) != head);
+ return error;
}
/*
*/
static inline unsigned ext2_chunk_size(struct inode *inode)
{
- //return inode->i_sb->s_blocksize;
- return PAGE_SIZE;
+ //return inode->i_sb->s_blocksize;
+ return PAGE_SIZE;
}
static inline void ext2_put_page(struct page *page)
{
- kunmap(page);
- page_cache_release(page);
+ kunmap(page);
+ page_cache_release(page);
}
static inline unsigned long dir_pages(struct inode *inode)
{
- return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
+ return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
}
extern void set_page_clean(struct page *page);
static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to)
{
- struct inode *dir = page->mapping->host;
- int err = 0;
-
- dir->i_version = ++event;
- dir->i_size = (page->index << PAGE_CACHE_SHIFT) + to;
- SetPageUptodate(page);
- set_page_clean(page);
-
- //page->mapping->a_ops->commit_write(NULL, page, from, to);
- //if (IS_SYNC(dir))
- // err = waitfor_one_page(page);
- return err;
+ struct inode *dir = page->mapping->host;
+ int err = 0;
+
+ dir->i_version = ++event;
+ dir->i_size = (page->index << PAGE_CACHE_SHIFT) + to;
+ SetPageUptodate(page);
+ set_page_clean(page);
+
+ //page->mapping->a_ops->commit_write(NULL, page, from, to);
+ //if (IS_SYNC(dir))
+ // err = waitfor_one_page(page);
+ return err;
}
static void ext2_check_page(struct page *page)
{
- struct inode *dir = page->mapping->host;
- unsigned chunk_size = ext2_chunk_size(dir);
- char *kaddr = page_address(page);
- // u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
- unsigned offs, rec_len;
- unsigned limit = PAGE_CACHE_SIZE;
- ext2_dirent *p;
- char *error;
-
- if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
- limit = dir->i_size & ~PAGE_CACHE_MASK;
- if (limit & (chunk_size - 1)) {
- CERROR("limit %d dir size %lld index %ld\n",
- limit, dir->i_size, page->index);
- goto Ebadsize;
- }
- for (offs = limit; offs<PAGE_CACHE_SIZE; offs += chunk_size) {
- ext2_dirent *p = (ext2_dirent*)(kaddr + offs);
- p->rec_len = cpu_to_le16(chunk_size);
- }
- if (!limit)
- goto out;
- }
- for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
- p = (ext2_dirent *)(kaddr + offs);
- rec_len = le16_to_cpu(p->rec_len);
-
- if (rec_len < EXT2_DIR_REC_LEN(1))
- goto Eshort;
- if (rec_len & 3)
- goto Ealign;
- if (rec_len < EXT2_DIR_REC_LEN(p->name_len))
- goto Enamelen;
- if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
- goto Espan;
- // if (le32_to_cpu(p->inode) > max_inumber)
- //goto Einumber;
- }
- if (offs != limit)
- goto Eend;
+ struct inode *dir = page->mapping->host;
+ unsigned chunk_size = ext2_chunk_size(dir);
+ char *kaddr = page_address(page);
+ // u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
+ unsigned offs, rec_len;
+ unsigned limit = PAGE_CACHE_SIZE;
+ ext2_dirent *p;
+ char *error;
+
+ if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
+ limit = dir->i_size & ~PAGE_CACHE_MASK;
+ if (limit & (chunk_size - 1)) {
+ CERROR("limit %d dir size %lld index %ld\n",
+ limit, dir->i_size, page->index);
+ goto Ebadsize;
+ }
+ for (offs = limit; offs<PAGE_CACHE_SIZE; offs += chunk_size) {
+ ext2_dirent *p = (ext2_dirent*)(kaddr + offs);
+ p->rec_len = cpu_to_le16(chunk_size);
+ }
+ if (!limit)
+ goto out;
+ }
+ for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
+ p = (ext2_dirent *)(kaddr + offs);
+ rec_len = le16_to_cpu(p->rec_len);
+
+ if (rec_len < EXT2_DIR_REC_LEN(1))
+ goto Eshort;
+ if (rec_len & 3)
+ goto Ealign;
+ if (rec_len < EXT2_DIR_REC_LEN(p->name_len))
+ goto Enamelen;
+ if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
+ goto Espan;
+ // if (le32_to_cpu(p->inode) > max_inumber)
+ //goto Einumber;
+ }
+ if (offs != limit)
+ goto Eend;
out:
- SetPageChecked(page);
- return;
+ SetPageChecked(page);
+ return;
- /* Too bad, we had an error */
+ /* Too bad, we had an error */
Ebadsize:
- CERROR("ext2_check_page"
- "size of directory #%lu is not a multiple of chunk size\n",
- dir->i_ino
- );
- goto fail;
+ CERROR("ext2_check_page"
+ "size of directory #%lu is not a multiple of chunk size\n",
+ dir->i_ino
+ );
+ goto fail;
Eshort:
- error = "rec_len is smaller than minimal";
- goto bad_entry;
+ error = "rec_len is smaller than minimal";
+ goto bad_entry;
Ealign:
- error = "unaligned directory entry";
- goto bad_entry;
+ error = "unaligned directory entry";
+ goto bad_entry;
Enamelen:
- error = "rec_len is too small for name_len";
- goto bad_entry;
+ error = "rec_len is too small for name_len";
+ goto bad_entry;
Espan:
- error = "directory entry across blocks";
- goto bad_entry;
- //Einumber:
- // error = "inode out of bounds";
+ error = "directory entry across blocks";
+ goto bad_entry;
+ //Einumber:
+ // error = "inode out of bounds";
bad_entry:
- CERROR("ext2_check_page: bad entry in directory #%lu: %s - "
- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
- dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
- (unsigned long) le32_to_cpu(p->inode),
- rec_len, p->name_len);
- goto fail;
+ CERROR("ext2_check_page: bad entry in directory #%lu: %s - "
+ "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+ dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ (unsigned long) le32_to_cpu(p->inode),
+ rec_len, p->name_len);
+ goto fail;
Eend:
- p = (ext2_dirent *)(kaddr + offs);
- CERROR("ext2_check_page"
- "entry in directory #%lu spans the page boundary"
- "offset=%lu, inode=%lu",
- dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
- (unsigned long) le32_to_cpu(p->inode));
+ p = (ext2_dirent *)(kaddr + offs);
+ CERROR("ext2_check_page"
+ "entry in directory #%lu spans the page boundary"
+ "offset=%lu, inode=%lu",
+ dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ (unsigned long) le32_to_cpu(p->inode));
fail:
- SetPageChecked(page);
- SetPageError(page);
- BUG();
+ SetPageChecked(page);
+ SetPageError(page);
+ LBUG();
}
static struct page * ext2_get_page(struct inode *dir, unsigned long n)
{
- struct address_space *mapping = dir->i_mapping;
- struct page *page = read_cache_page(mapping, n,
- (filler_t*)mapping->a_ops->readpage, NULL);
- if (!IS_ERR(page)) {
- wait_on_page(page);
- kmap(page);
- if (!Page_Uptodate(page))
- goto fail;
- if (!PageChecked(page))
- ext2_check_page(page);
- if (PageError(page))
- goto fail;
- }
- return page;
+ struct address_space *mapping = dir->i_mapping;
+ struct page *page = read_cache_page(mapping, n,
+ (filler_t*)mapping->a_ops->readpage, NULL);
+ if (!IS_ERR(page)) {
+ wait_on_page(page);
+ kmap(page);
+ if (!Page_Uptodate(page))
+ goto fail;
+ if (!PageChecked(page))
+ ext2_check_page(page);
+ if (PageError(page))
+ goto fail;
+ }
+ return page;
fail:
- ext2_put_page(page);
- return ERR_PTR(-EIO);
+ ext2_put_page(page);
+ return ERR_PTR(-EIO);
}
/*
* len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller.
*/
static inline int ext2_match (int len, const char * const name,
- struct ext2_dir_entry_2 * de)
+ struct ext2_dir_entry_2 * de)
{
- if (len != de->name_len)
- return 0;
- if (!de->inode)
- return 0;
- return !memcmp(name, de->name, len);
+ if (len != de->name_len)
+ return 0;
+ if (!de->inode)
+ return 0;
+ return !memcmp(name, de->name, len);
}
/*
*/
static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
{
- return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
+ return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
}
static inline unsigned
ext2_validate_entry(char *base, unsigned offset, unsigned mask)
{
- ext2_dirent *de = (ext2_dirent*)(base + offset);
- ext2_dirent *p = (ext2_dirent*)(base + (offset&mask));
- while ((char*)p < (char*)de)
- p = ext2_next_entry(p);
- return (char *)p - base;
+ ext2_dirent *de = (ext2_dirent*)(base + offset);
+ ext2_dirent *p = (ext2_dirent*)(base + (offset&mask));
+ while ((char*)p < (char*)de)
+ p = ext2_next_entry(p);
+ return (char *)p - base;
}
static unsigned char ext2_filetype_table[EXT2_FT_MAX] = {
- [EXT2_FT_UNKNOWN] DT_UNKNOWN,
- [EXT2_FT_REG_FILE] DT_REG,
- [EXT2_FT_DIR] DT_DIR,
- [EXT2_FT_CHRDEV] DT_CHR,
- [EXT2_FT_BLKDEV] DT_BLK,
- [EXT2_FT_FIFO] DT_FIFO,
- [EXT2_FT_SOCK] DT_SOCK,
- [EXT2_FT_SYMLINK] DT_LNK,
+ [EXT2_FT_UNKNOWN] DT_UNKNOWN,
+ [EXT2_FT_REG_FILE] DT_REG,
+ [EXT2_FT_DIR] DT_DIR,
+ [EXT2_FT_CHRDEV] DT_CHR,
+ [EXT2_FT_BLKDEV] DT_BLK,
+ [EXT2_FT_FIFO] DT_FIFO,
+ [EXT2_FT_SOCK] DT_SOCK,
+ [EXT2_FT_SYMLINK] DT_LNK,
};
static unsigned int ll_dt2fmt[DT_WHT + 1] = {
- [EXT2_FT_UNKNOWN] 0,
- [EXT2_FT_REG_FILE] S_IFREG,
- [EXT2_FT_DIR] S_IFDIR,
- [EXT2_FT_CHRDEV] S_IFCHR,
- [EXT2_FT_BLKDEV] S_IFBLK,
- [EXT2_FT_FIFO] S_IFIFO,
- [EXT2_FT_SOCK] S_IFSOCK,
- [EXT2_FT_SYMLINK] S_IFLNK
+ [EXT2_FT_UNKNOWN] 0,
+ [EXT2_FT_REG_FILE] S_IFREG,
+ [EXT2_FT_DIR] S_IFDIR,
+ [EXT2_FT_CHRDEV] S_IFCHR,
+ [EXT2_FT_BLKDEV] S_IFBLK,
+ [EXT2_FT_FIFO] S_IFIFO,
+ [EXT2_FT_SOCK] S_IFSOCK,
+ [EXT2_FT_SYMLINK] S_IFLNK
};
-
+
#define S_SHIFT 12
static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = {
- [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE,
- [S_IFDIR >> S_SHIFT] EXT2_FT_DIR,
- [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV,
- [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV,
- [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO,
- [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK,
- [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK,
+ [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE,
+ [S_IFDIR >> S_SHIFT] EXT2_FT_DIR,
+ [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV,
+ [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV,
+ [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO,
+ [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK,
+ [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK,
};
static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)
{
- mode_t mode = inode->i_mode;
- de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+ mode_t mode = inode->i_mode;
+ de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
}
int
new_ll_readdir (struct file * filp, void * dirent, filldir_t filldir)
{
- loff_t pos = filp->f_pos;
- struct inode *inode = filp->f_dentry->d_inode;
- // XXX struct super_block *sb = inode->i_sb;
- unsigned offset = pos & ~PAGE_CACHE_MASK;
- unsigned long n = pos >> PAGE_CACHE_SHIFT;
- unsigned long npages = dir_pages(inode);
- unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
- unsigned char *types = NULL;
- int need_revalidate = (filp->f_version != inode->i_version);
-
- if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
- goto done;
-
- types = ext2_filetype_table;
-
- for ( ; n < npages; n++, offset = 0) {
- char *kaddr, *limit;
- ext2_dirent *de;
- struct page *page = ext2_get_page(inode, n);
-
- if (IS_ERR(page))
- continue;
- kaddr = page_address(page);
- if (need_revalidate) {
- offset = ext2_validate_entry(kaddr, offset, chunk_mask);
- need_revalidate = 0;
- }
- de = (ext2_dirent *)(kaddr+offset);
- limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1);
- for ( ;(char*)de <= limit; de = ext2_next_entry(de))
- if (de->inode) {
- int over;
- unsigned char d_type = DT_UNKNOWN;
-
- if (types && de->file_type < EXT2_FT_MAX)
- d_type = types[de->file_type];
-
- offset = (char *)de - kaddr;
- over = filldir(dirent, de->name, de->name_len,
- (n<<PAGE_CACHE_SHIFT) | offset,
- le32_to_cpu(de->inode), d_type);
- if (over) {
- ext2_put_page(page);
- goto done;
- }
- }
- ext2_put_page(page);
- }
+ loff_t pos = filp->f_pos;
+ struct inode *inode = filp->f_dentry->d_inode;
+ // XXX struct super_block *sb = inode->i_sb;
+ unsigned offset = pos & ~PAGE_CACHE_MASK;
+ unsigned long n = pos >> PAGE_CACHE_SHIFT;
+ unsigned long npages = dir_pages(inode);
+ unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
+ unsigned char *types = NULL;
+ int need_revalidate = (filp->f_version != inode->i_version);
+
+ if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
+ goto done;
+
+ types = ext2_filetype_table;
+
+ for ( ; n < npages; n++, offset = 0) {
+ char *kaddr, *limit;
+ ext2_dirent *de;
+ struct page *page = ext2_get_page(inode, n);
+
+ if (IS_ERR(page))
+ continue;
+ kaddr = page_address(page);
+ if (need_revalidate) {
+ offset = ext2_validate_entry(kaddr, offset, chunk_mask);
+ need_revalidate = 0;
+ }
+ de = (ext2_dirent *)(kaddr+offset);
+ limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1);
+ for ( ;(char*)de <= limit; de = ext2_next_entry(de))
+ if (de->inode) {
+ int over;
+ unsigned char d_type = DT_UNKNOWN;
+
+ if (types && de->file_type < EXT2_FT_MAX)
+ d_type = types[de->file_type];
+
+ offset = (char *)de - kaddr;
+ over = filldir(dirent, de->name, de->name_len,
+ (n<<PAGE_CACHE_SHIFT) | offset,
+ le32_to_cpu(de->inode), d_type);
+ if (over) {
+ ext2_put_page(page);
+ goto done;
+ }
+ }
+ ext2_put_page(page);
+ }
done:
- filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
- filp->f_version = inode->i_version;
- UPDATE_ATIME(inode);
- return 0;
+ filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
+ filp->f_version = inode->i_version;
+ UPDATE_ATIME(inode);
+ return 0;
}
/*
- * ext2_find_entry()
+ * ext2_find_entry()
*
* finds an entry in the specified directory with the wanted name. It
* returns the page in which the entry was found, and the entry itself
* Entry is guaranteed to be valid.
*/
struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
- struct dentry *dentry, struct page ** res_page)
+ struct dentry *dentry, struct page ** res_page)
{
- const char *name = dentry->d_name.name;
- int namelen = dentry->d_name.len;
- unsigned reclen = EXT2_DIR_REC_LEN(namelen);
- unsigned long start, n;
- unsigned long npages = dir_pages(dir);
- struct page *page = NULL;
- ext2_dirent * de;
-
- /* OFFSET_CACHE */
- *res_page = NULL;
-
- // start = dir->u.ext2_i.i_dir_start_lookup;
- start = 0;
- if (start >= npages)
- start = 0;
- n = start;
- do {
- char *kaddr;
- page = ext2_get_page(dir, n);
- if (!IS_ERR(page)) {
- kaddr = page_address(page);
- de = (ext2_dirent *) kaddr;
- kaddr += PAGE_CACHE_SIZE - reclen;
- while ((char *) de <= kaddr) {
- if (ext2_match (namelen, name, de))
- goto found;
- de = ext2_next_entry(de);
- }
- ext2_put_page(page);
- }
- if (++n >= npages)
- n = 0;
- } while (n != start);
- return NULL;
+ const char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ unsigned reclen = EXT2_DIR_REC_LEN(namelen);
+ unsigned long start, n;
+ unsigned long npages = dir_pages(dir);
+ struct page *page = NULL;
+ ext2_dirent * de;
+
+ /* OFFSET_CACHE */
+ *res_page = NULL;
+
+ // start = dir->u.ext2_i.i_dir_start_lookup;
+ start = 0;
+ if (start >= npages)
+ start = 0;
+ n = start;
+ do {
+ char *kaddr;
+ page = ext2_get_page(dir, n);
+ if (!IS_ERR(page)) {
+ kaddr = page_address(page);
+ de = (ext2_dirent *) kaddr;
+ kaddr += PAGE_CACHE_SIZE - reclen;
+ while ((char *) de <= kaddr) {
+ if (ext2_match (namelen, name, de))
+ goto found;
+ de = ext2_next_entry(de);
+ }
+ ext2_put_page(page);
+ }
+ if (++n >= npages)
+ n = 0;
+ } while (n != start);
+ return NULL;
found:
- *res_page = page;
- // dir->u.ext2_i.i_dir_start_lookup = n;
- return de;
+ *res_page = page;
+ // dir->u.ext2_i.i_dir_start_lookup = n;
+ return de;
}
struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
{
- struct page *page = ext2_get_page(dir, 0);
- ext2_dirent *de = NULL;
-
- if (!IS_ERR(page)) {
- de = ext2_next_entry((ext2_dirent *) page_address(page));
- *p = page;
- }
- return de;
+ struct page *page = ext2_get_page(dir, 0);
+ ext2_dirent *de = NULL;
+
+ if (!IS_ERR(page)) {
+ de = ext2_next_entry((ext2_dirent *) page_address(page));
+ *p = page;
+ }
+ return de;
}
ino_t ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *type)
{
- ino_t res = 0;
- struct ext2_dir_entry_2 * de;
- struct page *page;
-
- de = ext2_find_entry (dir, dentry, &page);
- if (de) {
- res = le32_to_cpu(de->inode);
- *type = ll_dt2fmt[de->file_type];
- kunmap(page);
- page_cache_release(page);
- }
- return res;
+ ino_t res = 0;
+ struct ext2_dir_entry_2 * de;
+ struct page *page;
+
+ de = ext2_find_entry (dir, dentry, &page);
+ if (de) {
+ res = le32_to_cpu(de->inode);
+ *type = ll_dt2fmt[de->file_type];
+ kunmap(page);
+ page_cache_release(page);
+ }
+ return res;
}
/* Releases the page */
void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
- struct page *page, struct inode *inode)
+ struct page *page, struct inode *inode)
{
- unsigned from = (char *) de - (char *) page_address(page);
- unsigned to = from + le16_to_cpu(de->rec_len);
- int err;
-
- lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- BUG();
- de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- err = ext2_commit_chunk(page, from, to);
- UnlockPage(page);
- ext2_put_page(page);
+ unsigned from = (char *) de - (char *) page_address(page);
+ unsigned to = from + le16_to_cpu(de->rec_len);
+ int err;
+
+ lock_page(page);
+ err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ if (err)
+ LBUG();
+ de->inode = cpu_to_le32(inode->i_ino);
+ ext2_set_de_type (de, inode);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ err = ext2_commit_chunk(page, from, to);
+ UnlockPage(page);
+ ext2_put_page(page);
}
/*
- * Parent is locked.
+ * Parent is locked.
*/
int ll_add_link (struct dentry *dentry, struct inode *inode)
{
- struct inode *dir = dentry->d_parent->d_inode;
- const char *name = dentry->d_name.name;
- int namelen = dentry->d_name.len;
- unsigned reclen = EXT2_DIR_REC_LEN(namelen);
- unsigned short rec_len, name_len;
- struct page *page = NULL;
- ext2_dirent * de;
- unsigned long npages = dir_pages(dir);
- unsigned long n;
- char *kaddr;
- unsigned from, to;
- int err;
-
- /* We take care of directory expansion in the same loop */
- for (n = 0; n <= npages; n++) {
- page = ext2_get_page(dir, n);
- err = PTR_ERR(page);
- if (IS_ERR(page))
- goto out;
- kaddr = page_address(page);
- de = (ext2_dirent *)kaddr;
- kaddr += PAGE_CACHE_SIZE - reclen;
- while ((char *)de <= kaddr) {
- err = -EEXIST;
- if (ext2_match (namelen, name, de))
- goto out_page;
- name_len = EXT2_DIR_REC_LEN(de->name_len);
- rec_len = le16_to_cpu(de->rec_len);
- if ( n==npages && rec_len == 0) {
- CERROR("Fatal dir behaviour\n");
- goto out_page;
- }
- if (!de->inode && rec_len >= reclen)
- goto got_it;
- if (rec_len >= name_len + reclen)
- goto got_it;
- de = (ext2_dirent *) ((char *) de + rec_len);
- }
- ext2_put_page(page);
- }
- BUG();
- return -EINVAL;
+ struct inode *dir = dentry->d_parent->d_inode;
+ const char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ unsigned reclen = EXT2_DIR_REC_LEN(namelen);
+ unsigned short rec_len, name_len;
+ struct page *page = NULL;
+ ext2_dirent * de;
+ unsigned long npages = dir_pages(dir);
+ unsigned long n;
+ char *kaddr;
+ unsigned from, to;
+ int err;
+
+ /* We take care of directory expansion in the same loop */
+ for (n = 0; n <= npages; n++) {
+ page = ext2_get_page(dir, n);
+ err = PTR_ERR(page);
+ if (IS_ERR(page))
+ goto out;
+ kaddr = page_address(page);
+ de = (ext2_dirent *)kaddr;
+ kaddr += PAGE_CACHE_SIZE - reclen;
+ while ((char *)de <= kaddr) {
+ err = -EEXIST;
+ if (ext2_match (namelen, name, de))
+ goto out_page;
+ name_len = EXT2_DIR_REC_LEN(de->name_len);
+ rec_len = le16_to_cpu(de->rec_len);
+ if ( n==npages && rec_len == 0) {
+ CERROR("Fatal dir behaviour\n");
+ goto out_page;
+ }
+ if (!de->inode && rec_len >= reclen)
+ goto got_it;
+ if (rec_len >= name_len + reclen)
+ goto got_it;
+ de = (ext2_dirent *) ((char *) de + rec_len);
+ }
+ ext2_put_page(page);
+ }
+ LBUG();
+ return -EINVAL;
got_it:
- from = (char*)de - (char*)page_address(page);
- to = from + rec_len;
- lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- goto out_unlock;
- if (de->inode) {
- ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
- de1->rec_len = cpu_to_le16(rec_len - name_len);
- de->rec_len = cpu_to_le16(name_len);
- de = de1;
- }
- de->name_len = namelen;
- memcpy (de->name, name, namelen);
- de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
- CDEBUG(D_INODE, "type set to %o\n", de->file_type);
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- err = ext2_commit_chunk(page, from, to);
-
- // change_inode happens with the commit_chunk
- /* XXX OFFSET_CACHE */
+ from = (char*)de - (char*)page_address(page);
+ to = from + rec_len;
+ lock_page(page);
+ err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ if (err)
+ goto out_unlock;
+ if (de->inode) {
+ ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
+ de1->rec_len = cpu_to_le16(rec_len - name_len);
+ de->rec_len = cpu_to_le16(name_len);
+ de = de1;
+ }
+ de->name_len = namelen;
+ memcpy (de->name, name, namelen);
+ de->inode = cpu_to_le32(inode->i_ino);
+ ext2_set_de_type (de, inode);
+ CDEBUG(D_INODE, "type set to %o\n", de->file_type);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ err = ext2_commit_chunk(page, from, to);
+
+ // change_inode happens with the commit_chunk
+ /* XXX OFFSET_CACHE */
out_unlock:
- UnlockPage(page);
+ UnlockPage(page);
out_page:
- ext2_put_page(page);
+ ext2_put_page(page);
out:
- return err;
+ return err;
}
/*
*/
int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
{
- struct address_space *mapping = page->mapping;
- struct inode *inode = mapping->host;
- char *kaddr = page_address(page);
- unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
- unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
- ext2_dirent * pde = NULL;
- ext2_dirent * de = (ext2_dirent *) (kaddr + from);
- int err;
-
- while ((char*)de < (char*)dir) {
- pde = de;
- de = ext2_next_entry(de);
- }
- if (pde)
- from = (char*)pde - (char*)page_address(page);
- lock_page(page);
- err = mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- BUG();
- if (pde)
- pde->rec_len = cpu_to_le16(to-from);
- dir->inode = 0;
- inode->i_ctime = inode->i_mtime = CURRENT_TIME;
- err = ext2_commit_chunk(page, from, to);
- UnlockPage(page);
- ext2_put_page(page);
- return err;
+ struct address_space *mapping = page->mapping;
+ struct inode *inode = mapping->host;
+ char *kaddr = page_address(page);
+ unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
+ unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
+ ext2_dirent * pde = NULL;
+ ext2_dirent * de = (ext2_dirent *) (kaddr + from);
+ int err;
+
+ while ((char*)de < (char*)dir) {
+ pde = de;
+ de = ext2_next_entry(de);
+ }
+ if (pde)
+ from = (char*)pde - (char*)page_address(page);
+ lock_page(page);
+ err = mapping->a_ops->prepare_write(NULL, page, from, to);
+ if (err)
+ LBUG();
+ if (pde)
+ pde->rec_len = cpu_to_le16(to-from);
+ dir->inode = 0;
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+ err = ext2_commit_chunk(page, from, to);
+ UnlockPage(page);
+ ext2_put_page(page);
+ return err;
}
/*
*/
int ext2_make_empty(struct inode *inode, struct inode *parent)
{
- struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
- unsigned chunk_size = ext2_chunk_size(inode);
- struct ext2_dir_entry_2 * de;
- char *base;
- int err;
- ENTRY;
-
- if (!page)
- return -ENOMEM;
- err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
- if (err)
- goto fail;
-
- base = page_address(page);
-
- de = (struct ext2_dir_entry_2 *) base;
- de->name_len = 1;
- de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
- memcpy (de->name, ".\0\0", 4);
- de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
-
- de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1));
- de->name_len = 2;
- de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
- de->inode = cpu_to_le32(parent->i_ino);
- memcpy (de->name, "..\0", 4);
- ext2_set_de_type (de, inode);
-
- err = ext2_commit_chunk(page, 0, chunk_size);
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page = grab_cache_page(mapping, 0);
+ unsigned chunk_size = ext2_chunk_size(inode);
+ struct ext2_dir_entry_2 * de;
+ char *base;
+ int err;
+ ENTRY;
+
+ if (!page)
+ return -ENOMEM;
+ err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
+ if (err)
+ goto fail;
+
+ base = page_address(page);
+
+ de = (struct ext2_dir_entry_2 *) base;
+ de->name_len = 1;
+ de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
+ memcpy (de->name, ".\0\0", 4);
+ de->inode = cpu_to_le32(inode->i_ino);
+ ext2_set_de_type (de, inode);
+
+ de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1));
+ de->name_len = 2;
+ de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
+ de->inode = cpu_to_le32(parent->i_ino);
+ memcpy (de->name, "..\0", 4);
+ ext2_set_de_type (de, inode);
+
+ err = ext2_commit_chunk(page, 0, chunk_size);
fail:
- UnlockPage(page);
- page_cache_release(page);
- ENTRY;
- return err;
+ UnlockPage(page);
+ page_cache_release(page);
+ ENTRY;
+ return err;
}
/*
*/
int ext2_empty_dir (struct inode * inode)
{
- struct page *page = NULL;
- unsigned long i, npages = dir_pages(inode);
-
- for (i = 0; i < npages; i++) {
- char *kaddr;
- ext2_dirent * de;
- page = ext2_get_page(inode, i);
-
- if (IS_ERR(page))
- continue;
-
- kaddr = page_address(page);
- de = (ext2_dirent *)kaddr;
- kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1);
-
- while ((char *)de <= kaddr) {
- if (de->inode != 0) {
- /* check for . and .. */
- if (de->name[0] != '.')
- goto not_empty;
- if (de->name_len > 2)
- goto not_empty;
- if (de->name_len < 2) {
- if (de->inode !=
- cpu_to_le32(inode->i_ino))
- goto not_empty;
- } else if (de->name[1] != '.')
- goto not_empty;
- }
- de = ext2_next_entry(de);
- }
- ext2_put_page(page);
- }
- return 1;
+ struct page *page = NULL;
+ unsigned long i, npages = dir_pages(inode);
+
+ for (i = 0; i < npages; i++) {
+ char *kaddr;
+ ext2_dirent * de;
+ page = ext2_get_page(inode, i);
+
+ if (IS_ERR(page))
+ continue;
+
+ kaddr = page_address(page);
+ de = (ext2_dirent *)kaddr;
+ kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1);
+
+ while ((char *)de <= kaddr) {
+ if (de->inode != 0) {
+ /* check for . and .. */
+ if (de->name[0] != '.')
+ goto not_empty;
+ if (de->name_len > 2)
+ goto not_empty;
+ if (de->name_len < 2) {
+ if (de->inode !=
+ cpu_to_le32(inode->i_ino))
+ goto not_empty;
+ } else if (de->name[1] != '.')
+ goto not_empty;
+ }
+ de = ext2_next_entry(de);
+ }
+ ext2_put_page(page);
+ }
+ return 1;
not_empty:
- ext2_put_page(page);
- return 0;
+ ext2_put_page(page);
+ return 0;
}
struct file_operations ll_dir_operations = {
ENTRY;
if (file->private_data)
- BUG();
+ LBUG();
fd = kmem_cache_alloc(ll_file_data_slab, SLAB_KERNEL);
if (!fd) {
oa = ll_oa_from_inode(inode, (OBD_MD_FLMODE | OBD_MD_FLID));
if (oa == NULL)
- BUG();
+ LBUG();
rc = obd_open(ll_i2obdconn(inode), oa);
obdo_free(oa);
if (rc) {
rc = mdc_open(&sbi->ll_mds_client, inode->i_ino, S_IFREG,
file->f_flags, &fd->fd_mdshandle, &req);
if (!fd->fd_mdshandle)
- BUG();
+ LBUG();
ptlrpc_free_req(req);
if (rc) {
fd = (struct ll_file_data *)file->private_data;
if (!fd || !fd->fd_mdshandle) {
- BUG();
+ LBUG();
rc = -EINVAL;
goto out;
}
oa = ll_oa_from_inode(inode, (OBD_MD_FLMODE | OBD_MD_FLID));
if (oa == NULL)
- BUG();
+ LBUG();
rc = obd_close(ll_i2obdconn(inode), oa);
obdo_free(oa);
if (rc) {
ino_t ll_inode_by_name(struct inode * dir, struct dentry *dentry, int *typ);
int ext2_make_empty(struct inode *inode, struct inode *parent);
struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
- struct dentry *dentry, struct page ** res_page);
+ struct dentry *dentry, struct page ** res_page);
int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page );
int ext2_empty_dir (struct inode * inode);
struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p);
void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
- struct page *page, struct inode *inode);
+ struct page *page, struct inode *inode);
/*
* Couple of helper functions - make the code slightly cleaner.
*/
static inline void ext2_inc_count(struct inode *inode)
{
- inode->i_nlink++;
+ inode->i_nlink++;
}
/* postpone the disk update until the inode really goes away */
static inline void ext2_dec_count(struct inode *inode)
{
- inode->i_nlink--;
+ inode->i_nlink--;
}
static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
{
- int err;
- err = ll_add_link(dentry, inode);
- if (!err) {
- d_instantiate(dentry, inode);
- return 0;
- }
- ext2_dec_count(inode);
- iput(inode);
- return err;
+ int err;
+ err = ll_add_link(dentry, inode);
+ if (!err) {
+ d_instantiate(dentry, inode);
+ return 0;
+ }
+ ext2_dec_count(inode);
+ iput(inode);
+ return err;
}
/* methods */
static struct dentry *ll_lookup(struct inode * dir, struct dentry *dentry)
{
- struct ptlrpc_request *request;
- struct inode * inode = NULL;
+ struct ptlrpc_request *request;
+ struct inode * inode = NULL;
struct ll_sb_info *sbi = ll_i2sbi(dir);
- int err;
- int type;
- ino_t ino;
-
+ int err;
+ int type;
+ ino_t ino;
+
ENTRY;
- if (dentry->d_name.len > EXT2_NAME_LEN)
- return ERR_PTR(-ENAMETOOLONG);
+ if (dentry->d_name.len > EXT2_NAME_LEN)
+ return ERR_PTR(-ENAMETOOLONG);
- ino = ll_inode_by_name(dir, dentry, &type);
- if (!ino)
- goto negative;
+ ino = ll_inode_by_name(dir, dentry, &type);
+ if (!ino)
+ goto negative;
- err = mdc_getattr(&sbi->ll_mds_client, ino, type,
- OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, &request);
+ err = mdc_getattr(&sbi->ll_mds_client, ino, type,
+ OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, &request);
if ( err ) {
CERROR("failure %d inode %ld\n", err, ino);
ptlrpc_free_req(request);
return ERR_PTR(-abs(err));
}
- inode = iget4(dir->i_sb, ino, NULL, request->rq_rep.mds);
+ inode = iget4(dir->i_sb, ino, NULL, request->rq_rep.mds);
ptlrpc_free_req(request);
- if (!inode)
- return ERR_PTR(-ENOMEM);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
negative:
- d_add(dentry, inode);
- return NULL;
+ d_add(dentry, inode);
+ return NULL;
}
}
static struct inode *ll_create_node(struct inode *dir, const char *name,
- int namelen, const char *tgt, int tgtlen,
- int mode, __u64 id)
+ int namelen, const char *tgt, int tgtlen,
+ int mode, __u64 id)
{
struct inode *inode;
- struct ptlrpc_request *request;
+ struct ptlrpc_request *request;
struct mds_rep *rep;
int err;
- time_t time = CURRENT_TIME;
+ time_t time = CURRENT_TIME;
struct ll_sb_info *sbi = ll_i2sbi(dir);
ENTRY;
- err = mdc_create(&sbi->ll_mds_client, dir, name, namelen, tgt, tgtlen,
- mode, id, current->uid, current->gid, time, &request);
- if (err) {
+ err = mdc_create(&sbi->ll_mds_client, dir, name, namelen, tgt, tgtlen,
+ mode, id, current->uid, current->gid, time, &request);
+ if (err) {
inode = ERR_PTR(err);
EXIT;
goto out;
- }
+ }
rep = request->rq_rep.mds;
- rep->valid = OBD_MD_FLNOTOBD;
+ rep->valid = OBD_MD_FLNOTOBD;
- rep->objid = id;
- rep->nlink = 1;
- rep->atime = rep->ctime = rep->mtime = time;
- rep->mode = mode;
+ rep->objid = id;
+ rep->nlink = 1;
+ rep->atime = rep->ctime = rep->mtime = time;
+ rep->mode = mode;
CDEBUG(D_INODE, "-- new_inode: objid %lld, ino %d, mode %o\n",
- rep->objid, rep->ino, rep->mode);
+ rep->objid, rep->ino, rep->mode);
inode = iget4(dir->i_sb, rep->ino, NULL, rep);
if (IS_ERR(inode)) {
CERROR("new_inode -fatal: %ld\n", PTR_ERR(inode));
inode = ERR_PTR(-EIO);
- BUG();
+ LBUG();
EXIT;
goto out;
}
if (!list_empty(&inode->i_dentry)) {
CERROR("new_inode -fatal: aliases %d, ct %d lnk %d\n",
- rep->ino, atomic_read(&inode->i_count),
- inode->i_nlink);
+ rep->ino, atomic_read(&inode->i_count),
+ inode->i_nlink);
iput(inode);
- BUG();
+ LBUG();
inode = ERR_PTR(-EIO);
EXIT;
goto out;
int ll_mdc_unlink(struct inode *dir, const char *name, int len)
{
- struct ptlrpc_request *request;
+ struct ptlrpc_request *request;
int err;
struct ll_sb_info *sbi = ll_i2sbi(dir);
ENTRY;
- err = mdc_unlink(&sbi->ll_mds_client, dir, name, len, &request);
+ err = mdc_unlink(&sbi->ll_mds_client, dir, name, len, &request);
ptlrpc_free_req(request);
EXIT;
- return err;
+ return err;
}
int ll_mdc_link(struct dentry *src, struct inode *dir,
- const char *name, int len)
+ const char *name, int len)
{
- struct ptlrpc_request *request;
+ struct ptlrpc_request *request;
int err;
struct ll_sb_info *sbi = ll_i2sbi(dir);
ENTRY;
- err = mdc_link(&sbi->ll_mds_client, src, dir, name, len, &request);
+ err = mdc_link(&sbi->ll_mds_client, src, dir, name, len, &request);
ptlrpc_free_req(request);
EXIT;
- return err;
+ return err;
}
int ll_mdc_rename(struct inode *src, struct inode *tgt,
- struct dentry *old, struct dentry *new)
+ struct dentry *old, struct dentry *new)
{
- struct ptlrpc_request *request;
+ struct ptlrpc_request *request;
int err;
struct ll_sb_info *sbi = ll_i2sbi(src);
ENTRY;
- err = mdc_rename(&sbi->ll_mds_client, src, tgt,
- old->d_name.name, old->d_name.len,
- new->d_name.name, new->d_name.len, &request);
+ err = mdc_rename(&sbi->ll_mds_client, src, tgt,
+ old->d_name.name, old->d_name.len,
+ new->d_name.name, new->d_name.len, &request);
ptlrpc_free_req(request);
EXIT;
- return err;
+ return err;
}
/*
static int ll_create (struct inode * dir, struct dentry * dentry, int mode)
{
- int err;
- struct obdo oa;
- struct inode * inode;
-
- memset(&oa, 0, sizeof(oa));
- oa.o_valid = OBD_MD_FLMODE;
- oa.o_mode = S_IFREG | 0600;
- err = obd_create(ll_i2obdconn(dir), &oa);
- if (err) {
- EXIT;
- return err;
- }
-
- mode = mode | S_IFREG;
+ int err;
+ struct obdo oa;
+ struct inode * inode;
+
+ memset(&oa, 0, sizeof(oa));
+ oa.o_valid = OBD_MD_FLMODE;
+ oa.o_mode = S_IFREG | 0600;
+ err = obd_create(ll_i2obdconn(dir), &oa);
+ if (err) {
+ EXIT;
+ return err;
+ }
+
+ mode = mode | S_IFREG;
CDEBUG(D_DENTRY, "name %s mode %o o_id %lld\n",
- dentry->d_name.name, mode, oa.o_id);
- inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len,
- NULL, 0, mode, oa.o_id);
- err = PTR_ERR(inode);
- if (!IS_ERR(inode)) {
- // XXX clean up the object
- inode->i_op = &ll_file_inode_operations;
- inode->i_fop = &ll_file_operations;
- inode->i_mapping->a_ops = &ll_aops;
- err = ext2_add_nondir(dentry, inode);
- }
- EXIT;
- return err;
+ dentry->d_name.name, mode, oa.o_id);
+ inode = ll_create_node(dir, dentry->d_name.name, dentry->d_name.len,
+ NULL, 0, mode, oa.o_id);
+ err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ // XXX clean up the object
+ inode->i_op = &ll_file_inode_operations;
+ inode->i_fop = &ll_file_operations;
+ inode->i_mapping->a_ops = &ll_aops;
+ err = ext2_add_nondir(dentry, inode);
+ }
+ EXIT;
+ return err;
} /* ll_create */
static int ll_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
{
- struct inode * inode = ll_create_node(dir, dentry->d_name.name,
- dentry->d_name.len, NULL, 0,
- mode, 0);
- int err = PTR_ERR(inode);
- if (!IS_ERR(inode)) {
- init_special_inode(inode, mode, rdev);
- err = ext2_add_nondir(dentry, inode);
- }
- return err;
+ struct inode * inode = ll_create_node(dir, dentry->d_name.name,
+ dentry->d_name.len, NULL, 0,
+ mode, 0);
+ int err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ init_special_inode(inode, mode, rdev);
+ err = ext2_add_nondir(dentry, inode);
+ }
+ return err;
}
static int ll_symlink (struct inode * dir, struct dentry * dentry,
- const char * symname)
+ const char * symname)
{
- int err = -ENAMETOOLONG;
- unsigned l = strlen(symname);
- struct inode * inode;
+ int err = -ENAMETOOLONG;
+ unsigned l = strlen(symname);
+ struct inode * inode;
struct ll_inode_info *oinfo;
- if (l > LL_INLINESZ)
- return err;
+ if (l > LL_INLINESZ)
+ return err;
- inode = ll_create_node(dir, dentry->d_name.name,
- dentry->d_name.len, symname, l,
- S_IFLNK | S_IRWXUGO, 0);
- err = PTR_ERR(inode);
- if (IS_ERR(inode))
- return err;
+ inode = ll_create_node(dir, dentry->d_name.name,
+ dentry->d_name.len, symname, l,
+ S_IFLNK | S_IRWXUGO, 0);
+ err = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ return err;
oinfo = ll_i2info(inode);
-
- inode->i_op = &ll_fast_symlink_inode_operations;
- memcpy(oinfo->lli_inline, symname, l);
- inode->i_size = l-1;
-
- err = ext2_add_nondir(dentry, inode);
-
- if (err) {
- ext2_dec_count(inode);
- iput (inode);
- }
- return err;
+
+ inode->i_op = &ll_fast_symlink_inode_operations;
+ memcpy(oinfo->lli_inline, symname, l);
+ inode->i_size = l-1;
+
+ err = ext2_add_nondir(dentry, inode);
+
+ if (err) {
+ ext2_dec_count(inode);
+ iput (inode);
+ }
+ return err;
}
static int ll_link (struct dentry * old_dentry, struct inode * dir,
- struct dentry *dentry)
+ struct dentry *dentry)
{
- int err;
- struct inode *inode = old_dentry->d_inode;
+ int err;
+ struct inode *inode = old_dentry->d_inode;
- if (S_ISDIR(inode->i_mode))
- return -EPERM;
+ if (S_ISDIR(inode->i_mode))
+ return -EPERM;
- if (inode->i_nlink >= EXT2_LINK_MAX)
- return -EMLINK;
+ if (inode->i_nlink >= EXT2_LINK_MAX)
+ return -EMLINK;
- err = ll_mdc_link(old_dentry, dir,
- dentry->d_name.name, dentry->d_name.len);
- if (err) {
- EXIT;
- return err;
- }
+ err = ll_mdc_link(old_dentry, dir,
+ dentry->d_name.name, dentry->d_name.len);
+ if (err) {
+ EXIT;
+ return err;
+ }
- inode->i_ctime = CURRENT_TIME;
- ext2_inc_count(inode);
- atomic_inc(&inode->i_count);
+ inode->i_ctime = CURRENT_TIME;
+ ext2_inc_count(inode);
+ atomic_inc(&inode->i_count);
- return ext2_add_nondir(dentry, inode);
+ return ext2_add_nondir(dentry, inode);
}
static int ll_mkdir(struct inode * dir, struct dentry * dentry, int mode)
{
- struct inode * inode;
- int err = -EMLINK;
- ENTRY;
+ struct inode * inode;
+ int err = -EMLINK;
+ ENTRY;
- if (dir->i_nlink >= EXT2_LINK_MAX)
- goto out;
+ if (dir->i_nlink >= EXT2_LINK_MAX)
+ goto out;
- ext2_inc_count(dir);
+ ext2_inc_count(dir);
- inode = ll_create_node (dir, dentry->d_name.name,
- dentry->d_name.len, NULL, 0,
- S_IFDIR | mode, 0);
- err = PTR_ERR(inode);
- if (IS_ERR(inode))
- goto out_dir;
+ inode = ll_create_node (dir, dentry->d_name.name,
+ dentry->d_name.len, NULL, 0,
+ S_IFDIR | mode, 0);
+ err = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ goto out_dir;
- inode->i_op = &ll_dir_inode_operations;
- inode->i_fop = &ll_dir_operations;
- inode->i_mapping->a_ops = &ll_aops;
- inode->i_nlink = 1;
- ext2_inc_count(inode);
+ inode->i_op = &ll_dir_inode_operations;
+ inode->i_fop = &ll_dir_operations;
+ inode->i_mapping->a_ops = &ll_aops;
+ inode->i_nlink = 1;
+ ext2_inc_count(inode);
- err = ext2_make_empty(inode, dir);
- if (err)
- goto out_fail;
+ err = ext2_make_empty(inode, dir);
+ if (err)
+ goto out_fail;
- err = ll_add_link(dentry, inode);
- if (err)
- goto out_fail;
+ err = ll_add_link(dentry, inode);
+ if (err)
+ goto out_fail;
- d_instantiate(dentry, inode);
+ d_instantiate(dentry, inode);
out:
- EXIT;
- return err;
+ EXIT;
+ return err;
out_fail:
- ext2_dec_count(inode);
- ext2_dec_count(inode);
- iput(inode);
- EXIT;
+ ext2_dec_count(inode);
+ ext2_dec_count(inode);
+ iput(inode);
+ EXIT;
out_dir:
- ext2_dec_count(dir);
- EXIT;
- goto out;
+ ext2_dec_count(dir);
+ EXIT;
+ goto out;
}
static int ll_unlink(struct inode * dir, struct dentry *dentry)
{
- struct inode * inode = dentry->d_inode;
- struct ext2_dir_entry_2 * de;
- struct page * page;
- int err = -ENOENT;
-
- de = ext2_find_entry (dir, dentry, &page);
- if (!de)
- goto out;
-
- err = ll_mdc_unlink(dir, dentry->d_name.name, dentry->d_name.len);
- if (err)
- goto out;
-
-
- err = ext2_delete_entry (de, page);
- if (err)
- goto out;
-
- inode->i_ctime = dir->i_ctime;
- ext2_dec_count(inode);
- err = 0;
+ struct inode * inode = dentry->d_inode;
+ struct ext2_dir_entry_2 * de;
+ struct page * page;
+ int err = -ENOENT;
+
+ de = ext2_find_entry (dir, dentry, &page);
+ if (!de)
+ goto out;
+
+ err = ll_mdc_unlink(dir, dentry->d_name.name, dentry->d_name.len);
+ if (err)
+ goto out;
+
+
+ err = ext2_delete_entry (de, page);
+ if (err)
+ goto out;
+
+ inode->i_ctime = dir->i_ctime;
+ ext2_dec_count(inode);
+ err = 0;
out:
- return err;
+ return err;
}
static int ll_rmdir (struct inode * dir, struct dentry *dentry)
{
- struct inode * inode = dentry->d_inode;
- int err = -ENOTEMPTY;
-
- if (ext2_empty_dir(inode)) {
- err = ll_unlink(dir, dentry);
- if (!err) {
- inode->i_size = 0;
- ext2_dec_count(inode);
- ext2_dec_count(dir);
- }
- }
- return err;
+ struct inode * inode = dentry->d_inode;
+ int err = -ENOTEMPTY;
+
+ if (ext2_empty_dir(inode)) {
+ err = ll_unlink(dir, dentry);
+ if (!err) {
+ inode->i_size = 0;
+ ext2_dec_count(inode);
+ ext2_dec_count(dir);
+ }
+ }
+ return err;
}
static int ll_rename (struct inode * old_dir, struct dentry * old_dentry,
- struct inode * new_dir, struct dentry * new_dentry )
+ struct inode * new_dir, struct dentry * new_dentry )
{
- struct inode * old_inode = old_dentry->d_inode;
- struct inode * new_inode = new_dentry->d_inode;
- struct page * dir_page = NULL;
- struct ext2_dir_entry_2 * dir_de = NULL;
- struct page * old_page;
- struct ext2_dir_entry_2 * old_de;
- int err = -ENOENT;
-
- err = ll_mdc_rename(old_dir, new_dir, old_dentry, new_dentry);
- if (err)
- goto out;
-
- old_de = ext2_find_entry (old_dir, old_dentry, &old_page);
- if (!old_de)
- goto out;
-
- if (S_ISDIR(old_inode->i_mode)) {
- err = -EIO;
- dir_de = ext2_dotdot(old_inode, &dir_page);
- if (!dir_de)
- goto out_old;
- }
-
- if (new_inode) {
- struct page *new_page;
- struct ext2_dir_entry_2 *new_de;
-
- err = -ENOTEMPTY;
- if (dir_de && !ext2_empty_dir (new_inode))
- goto out_dir;
-
- err = -ENOENT;
- new_de = ext2_find_entry (new_dir, new_dentry, &new_page);
- if (!new_de)
- goto out_dir;
- ext2_inc_count(old_inode);
- ext2_set_link(new_dir, new_de, new_page, old_inode);
- new_inode->i_ctime = CURRENT_TIME;
- if (dir_de)
- new_inode->i_nlink--;
- ext2_dec_count(new_inode);
- } else {
- if (dir_de) {
- err = -EMLINK;
- if (new_dir->i_nlink >= EXT2_LINK_MAX)
- goto out_dir;
- }
- ext2_inc_count(old_inode);
- err = ll_add_link(new_dentry, old_inode);
- if (err) {
- ext2_dec_count(old_inode);
- goto out_dir;
- }
- if (dir_de)
- ext2_inc_count(new_dir);
- }
-
- ext2_delete_entry (old_de, old_page);
- ext2_dec_count(old_inode);
-
- if (dir_de) {
- ext2_set_link(old_inode, dir_de, dir_page, new_dir);
- ext2_dec_count(old_dir);
- }
- return 0;
+ struct inode * old_inode = old_dentry->d_inode;
+ struct inode * new_inode = new_dentry->d_inode;
+ struct page * dir_page = NULL;
+ struct ext2_dir_entry_2 * dir_de = NULL;
+ struct page * old_page;
+ struct ext2_dir_entry_2 * old_de;
+ int err = -ENOENT;
+
+ err = ll_mdc_rename(old_dir, new_dir, old_dentry, new_dentry);
+ if (err)
+ goto out;
+
+ old_de = ext2_find_entry (old_dir, old_dentry, &old_page);
+ if (!old_de)
+ goto out;
+
+ if (S_ISDIR(old_inode->i_mode)) {
+ err = -EIO;
+ dir_de = ext2_dotdot(old_inode, &dir_page);
+ if (!dir_de)
+ goto out_old;
+ }
+
+ if (new_inode) {
+ struct page *new_page;
+ struct ext2_dir_entry_2 *new_de;
+
+ err = -ENOTEMPTY;
+ if (dir_de && !ext2_empty_dir (new_inode))
+ goto out_dir;
+
+ err = -ENOENT;
+ new_de = ext2_find_entry (new_dir, new_dentry, &new_page);
+ if (!new_de)
+ goto out_dir;
+ ext2_inc_count(old_inode);
+ ext2_set_link(new_dir, new_de, new_page, old_inode);
+ new_inode->i_ctime = CURRENT_TIME;
+ if (dir_de)
+ new_inode->i_nlink--;
+ ext2_dec_count(new_inode);
+ } else {
+ if (dir_de) {
+ err = -EMLINK;
+ if (new_dir->i_nlink >= EXT2_LINK_MAX)
+ goto out_dir;
+ }
+ ext2_inc_count(old_inode);
+ err = ll_add_link(new_dentry, old_inode);
+ if (err) {
+ ext2_dec_count(old_inode);
+ goto out_dir;
+ }
+ if (dir_de)
+ ext2_inc_count(new_dir);
+ }
+
+ ext2_delete_entry (old_de, old_page);
+ ext2_dec_count(old_inode);
+
+ if (dir_de) {
+ ext2_set_link(old_inode, dir_de, dir_page, new_dir);
+ ext2_dec_count(old_dir);
+ }
+ return 0;
out_dir:
- if (dir_de) {
- kunmap(dir_page);
- page_cache_release(dir_page);
- }
+ if (dir_de) {
+ kunmap(dir_page);
+ page_cache_release(dir_page);
+ }
out_old:
- kunmap(old_page);
- page_cache_release(old_page);
+ kunmap(old_page);
+ page_cache_release(old_page);
out:
- return err;
+ return err;
}
struct inode_operations ll_dir_inode_operations = {
- create: ll_create,
- lookup: ll_lookup,
- link: ll_link,
- unlink: ll_unlink,
- symlink: ll_symlink,
- mkdir: ll_mkdir,
- rmdir: ll_rmdir,
- mknod: ll_mknod,
- rename: ll_rename,
- setattr: ll_setattr
+ create: ll_create,
+ lookup: ll_lookup,
+ link: ll_link,
+ unlink: ll_unlink,
+ symlink: ll_symlink,
+ mkdir: ll_mkdir,
+ rmdir: ll_rmdir,
+ mknod: ll_mknod,
+ rename: ll_rename,
+ setattr: ll_setattr
};
*/
void set_page_dirty(struct page *page)
{
- if (!test_and_set_bit(PG_dirty, &page->flags)) {
- struct address_space *mapping = page->mapping;
-
- if (mapping) {
- spin_lock(&pagecache_lock);
- list_del(&page->list);
- list_add(&page->list, &mapping->dirty_pages);
- spin_unlock(&pagecache_lock);
-
- if (mapping->host)
- mark_inode_dirty_pages(mapping->host);
- }
- }
+ if (!test_and_set_bit(PG_dirty, &page->flags)) {
+ struct address_space *mapping = page->mapping;
+
+ if (mapping) {
+ spin_lock(&pagecache_lock);
+ list_del(&page->list);
+ list_add(&page->list, &mapping->dirty_pages);
+ spin_unlock(&pagecache_lock);
+
+ if (mapping->host)
+ mark_inode_dirty_pages(mapping->host);
+ }
+ }
}
#endif
inline struct obdo * ll_oa_from_inode(struct inode *inode, int valid)
{
struct ll_inode_info *oinfo = ll_i2info(inode);
- struct obdo *oa = obdo_alloc();
+ struct obdo *oa = obdo_alloc();
if ( !oa ) {
- CERROR("no memory to allocate obdo!\n");
+ CERROR("no memory to allocate obdo!\n");
return NULL;
}
- oa->o_valid = valid;
+ oa->o_valid = valid;
if ( oa->o_valid & OBD_MD_FLID )
oa->o_id = oinfo->lli_objid;
CDEBUG(D_INFO, "src inode %ld, dst obdo %ld valid 0x%08x\n",
inode->i_ino, (long)oa->o_id, oa->o_valid);
#if 0
- /* this will transfer metadata for the logical object to
- the oa: that metadata could contain the constituent objects
- */
- if (ll_has_inline(inode)) {
+ /* this will transfer metadata for the logical object to
+ the oa: that metadata could contain the constituent objects
+ */
+ if (ll_has_inline(inode)) {
CDEBUG(D_INODE, "copying inline data from inode to obdo\n");
memcpy(oa->o_inline, oinfo->lli_inline, OBD_INLINESZ);
oa->o_obdflags |= OBD_FL_INLINEDATA;
oa->o_valid |= OBD_MD_FLINLINE;
}
#endif
- return oa;
+ return oa;
} /* ll_oa_from_inode */
*/
void __set_page_clean(struct page *page)
{
- struct address_space *mapping = page->mapping;
- struct inode *inode;
-
- if (!mapping)
- return;
-
- list_del(&page->list);
- list_add(&page->list, &mapping->clean_pages);
-
- inode = mapping->host;
- if (list_empty(&mapping->dirty_pages)) {
- CDEBUG(D_INODE, "inode clean\n");
- inode->i_state &= ~I_DIRTY_PAGES;
- }
- EXIT;
+ struct address_space *mapping = page->mapping;
+ struct inode *inode;
+
+ if (!mapping)
+ return;
+
+ list_del(&page->list);
+ list_add(&page->list, &mapping->clean_pages);
+
+ inode = mapping->host;
+ if (list_empty(&mapping->dirty_pages)) {
+ CDEBUG(D_INODE, "inode clean\n");
+ inode->i_state &= ~I_DIRTY_PAGES;
+ }
+ EXIT;
}
/* SYNCHRONOUS I/O to object storage for an inode */
ENTRY;
oa = ll_oa_from_inode(inode, OBD_MD_FLNOTOBD);
- if (!oa) {
- return -ENOMEM;
- }
+ if (!oa) {
+ return -ENOMEM;
+ }
err = obd_brw(rw, ll_i2obdconn(inode), num_obdo, &oa, &bufs_per_obdo,
&page, &count, &offset, &flags);
/* returns the page unlocked, but with a reference */
static int ll_readpage(struct file *file, struct page *page)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = page->mapping->host;
int rc = 0;
ENTRY;
if (!PageLocked(page))
- BUG();
+ LBUG();
- if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT)
+ if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT)
<= page->index) {
- memset(kmap(page), 0, PAGE_CACHE_SIZE);
- kunmap(page);
+ memset(kmap(page), 0, PAGE_CACHE_SIZE);
+ kunmap(page);
EXIT;
- goto readpage_out;
- }
+ goto readpage_out;
+ }
- if (Page_Uptodate(page)) {
+ if (Page_Uptodate(page)) {
CERROR("Explain this please?\n");
- EXIT;
- goto readpage_out;
- }
+ EXIT;
+ goto readpage_out;
+ }
rc = ll_brw(OBD_BRW_READ, inode, page, 0);
EXIT;
readpage_out:
if (!rc)
SetPageUptodate(page);
- UnlockPage(page);
+ UnlockPage(page);
return 0;
} /* ll_readpage */
struct inode *inode = page->mapping->host;
obd_off offset = ((obd_off)page->index) << PAGE_SHIFT;
int rc = 0;
- char *addr;
+ char *addr;
ENTRY;
- addr = kmap(page);
+ addr = kmap(page);
if (!PageLocked(page))
- BUG();
+ LBUG();
if (Page_Uptodate(page)) {
EXIT;
- goto prepare_done;
+ goto prepare_done;
}
if (offset + from >= inode->i_size) {
- memset(addr, 0, PAGE_SIZE);
+ memset(addr, 0, PAGE_SIZE);
EXIT;
goto prepare_done;
}
- /* 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);
- RETURN(0);
- }
+ /* 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);
+ RETURN(0);
+ }
rc = ll_brw(OBD_BRW_READ, inode, page, 0);
int err;
ENTRY;
- BUG();
+ LBUG();
if (!PageLocked(page))
- BUG();
+ LBUG();
- err = ll_brw(OBD_BRW_WRITE, inode, page, 1);
+ err = ll_brw(OBD_BRW_WRITE, inode, page, 1);
if ( !err ) {
//SetPageUptodate(page);
- set_page_clean(page);
- } else {
- CERROR("ll_brw failure %d\n", err);
- }
+ set_page_clean(page);
+ } else {
+ CERROR("ll_brw failure %d\n", err);
+ }
UnlockPage(page);
EXIT;
- return err;
+ return err;
}
/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated
static int ll_commit_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
- int create = 1;
- struct inode *inode = page->mapping->host;
+ int create = 1;
+ struct inode *inode = page->mapping->host;
obd_count num_obdo = 1;
obd_count bufs_per_obdo = 1;
struct obdo *oa;
obd_off offset = (((obd_off)page->index) << PAGE_SHIFT);
obd_flag flags = create ? OBD_BRW_CREATE : 0;
int err;
- struct iattr iattr;
+ struct iattr iattr;
ENTRY;
oa = ll_oa_from_inode(inode, OBD_MD_FLNOTOBD);
- if (! oa )
- RETURN(-ENOMEM);
+ if (! oa )
+ RETURN(-ENOMEM);
- SetPageUptodate(page);
+ SetPageUptodate(page);
if (!PageLocked(page))
- BUG();
+ LBUG();
- CDEBUG(D_INODE, "commit_page writing (at %d) to %d, count %Ld\n",
- from, to, count);
+ CDEBUG(D_INODE, "commit_page writing (at %d) to %d, count %Ld\n",
+ from, to, count);
err = obd_brw(OBD_BRW_WRITE, ll_i2obdconn(inode), num_obdo, &oa,
&bufs_per_obdo, &page, &count, &offset, &flags);
kunmap(page);
- if (offset + to > inode->i_size) {
- iattr.ia_valid = ATTR_SIZE;
- iattr.ia_size = offset + to;
- /* do NOT truncate */
- err = ll_inode_setattr(inode, &iattr, 0);
- if (err) {
- CERROR("failed - %d.\n", err);
+ if (offset + to > inode->i_size) {
+ iattr.ia_valid = ATTR_SIZE;
+ iattr.ia_size = offset + to;
+ /* do NOT truncate */
+ err = ll_inode_setattr(inode, &iattr, 0);
+ if (err) {
+ CERROR("failed - %d.\n", err);
err = -EIO;
- }
- }
+ }
+ }
obdo_free(oa);
EXIT;
int err;
ENTRY;
- oa = ll_oa_from_inode(inode, OBD_MD_FLNOTOBD);
+ oa = ll_oa_from_inode(inode, OBD_MD_FLNOTOBD);
if ( !oa ) {
CERROR("no memory to allocate obdo!\n");
- return;
+ return;
}
-
- CDEBUG(D_INFO, "calling punch for %ld (%Lu bytes at 0)\n",
- (long)oa->o_id, oa->o_size);
- err = obd_punch(ll_i2obdconn(inode), oa, oa->o_size, 0);
- obdo_free(oa);
+
+ CDEBUG(D_INFO, "calling punch for %ld (%Lu bytes at 0)\n",
+ (long)oa->o_id, oa->o_size);
+ err = obd_punch(ll_i2obdconn(inode), oa, oa->o_size, 0);
+ obdo_free(oa);
if (err) {
CERROR("obd_truncate fails (%d)\n", err);
}
EXIT;
- return;
+ return;
} /* ll_truncate */
struct address_space_operations ll_aops = {
int mdc_getattr(struct ptlrpc_client *cl, ino_t ino, int type, int valid,
- struct ptlrpc_request **req)
+ struct ptlrpc_request **req)
{
- int rc;
+ int rc;
struct ptlrpc_request *request;
ENTRY;
- request = ptlrpc_prep_req(cl, MDS_GETATTR, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("llight request: cannot pack\n");
- rc = -ENOMEM;
+ request = ptlrpc_prep_req(cl, MDS_GETATTR, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("llight request: cannot pack\n");
+ rc = -ENOMEM;
EXIT;
goto out;
- }
+ }
- ll_ino2fid(&request->rq_req.mds->fid1, ino, 0, type);
+ ll_ino2fid(&request->rq_req.mds->fid1, ino, 0, type);
- request->rq_req.mds->valid = valid;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
+ request->rq_req.mds->valid = valid;
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
- rc = ptlrpc_queue_wait(cl, request);
- rc = ptlrpc_check_status(request, rc);
+ rc = ptlrpc_queue_wait(cl, request);
+ rc = ptlrpc_check_status(request, rc);
if (!rc)
CDEBUG(D_NET, "mode: %o\n", request->rq_rep.mds->mode);
int mdc_open(struct ptlrpc_client *cl, ino_t ino, int type, int flags,
__u64 *fh, struct ptlrpc_request **req)
{
- struct ptlrpc_request *request;
- int rc;
+ struct ptlrpc_request *request;
+ int rc;
- request = ptlrpc_prep_req(cl, MDS_OPEN, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("llight request: cannot pack\n");
- rc = -ENOMEM;
+ request = ptlrpc_prep_req(cl, MDS_OPEN, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("llight request: cannot pack\n");
+ rc = -ENOMEM;
goto out;
- }
+ }
- ll_ino2fid(&request->rq_req.mds->fid1, ino, 0, type);
- request->rq_req.mds->flags = flags;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
+ ll_ino2fid(&request->rq_req.mds->fid1, ino, 0, type);
+ request->rq_req.mds->flags = HTON__u32(flags);
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
- rc = ptlrpc_queue_wait(cl, request);
- if (rc) {
- CERROR("llight request: error in handling %d\n", rc);
- goto out;
- }
+ rc = ptlrpc_queue_wait(cl, request);
+ rc = ptlrpc_check_status(request, rc);
- *fh = request->rq_rep.mds->objid;
+ if (rc) {
+ CERROR("llight request: error in handling %d\n", rc);
+ goto out;
+ }
+ *fh = request->rq_rep.mds->objid;
out:
*req = request;
- return rc;
+ return rc;
}
int mdc_close(struct ptlrpc_client *cl, ino_t ino, int type, __u64 fh,
struct ptlrpc_request **req)
{
- struct ptlrpc_request *request;
- int rc;
+ struct ptlrpc_request *request;
+ int rc;
- request = ptlrpc_prep_req(cl, MDS_CLOSE, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("llight request: cannot pack\n");
- rc = -ENOMEM;
+ request = ptlrpc_prep_req(cl, MDS_CLOSE, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("llight request: cannot pack\n");
+ rc = -ENOMEM;
goto out;
- }
+ }
- ll_ino2fid(&request->rq_req.mds->fid1, ino, 0, type);
+ ll_ino2fid(&request->rq_req.mds->fid1, ino, 0, type);
request->rq_req.mds->objid = fh;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
- rc = ptlrpc_queue_wait(cl, request);
- if (rc) {
- CERROR("llight request: error in handling %d\n", rc);
- goto out;
- }
+ rc = ptlrpc_queue_wait(cl, request);
+ rc = ptlrpc_check_status(request, rc);
+
+ if (rc) {
+ CERROR("llight request: error in handling %d\n", rc);
+ goto out;
+ }
out:
*req = request;
- return rc;
+ return rc;
}
int mdc_readpage(struct ptlrpc_client *cl, ino_t ino, int type, __u64 offset,
char *addr, struct ptlrpc_request **req)
{
- struct ptlrpc_request *request = NULL;
+ struct ptlrpc_request *request = NULL;
struct ptlrpc_bulk_desc *bulk = NULL;
- struct niobuf niobuf;
- int rc;
+ struct niobuf niobuf;
+ int rc;
- niobuf.addr = (__u64) (long) addr;
+ niobuf.addr = (__u64) (long) addr;
CDEBUG(D_INODE, "inode: %ld\n", ino);
goto out;
}
- request = ptlrpc_prep_req(cl, MDS_READPAGE, 0, NULL,
+ request = ptlrpc_prep_req(cl, MDS_READPAGE, 0, NULL,
sizeof(struct niobuf), (char *)&niobuf);
- if (!request) {
- CERROR("%s: cannot pack\n", __FUNCTION__);
- rc = -ENOMEM;
+ if (!request) {
+ CERROR("%s: cannot pack\n", __FUNCTION__);
+ rc = -ENOMEM;
goto out;
- }
+ }
bulk->b_buflen = PAGE_SIZE;
bulk->b_buf = (void *)(long)niobuf.addr;
- bulk->b_portal = MDS_BULK_PORTAL;
+ bulk->b_portal = MDS_BULK_PORTAL;
bulk->b_xid = request->rq_xid;
rc = ptlrpc_register_bulk(bulk);
goto out;
}
- request->rq_req.mds->fid1.id = ino;
- request->rq_req.mds->fid1.f_type = type;
- request->rq_req.mds->size = offset;
- request->rq_req.mds->tgtlen = sizeof(niobuf);
- request->rq_replen = sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
+ request->rq_req.mds->fid1.id = ino;
+ request->rq_req.mds->fid1.f_type = type;
+ request->rq_req.mds->size = offset;
+ request->rq_req.mds->tgtlen = sizeof(niobuf);
+ request->rq_replen = sizeof(struct ptlrep_hdr) + sizeof(struct mds_rep);
- rc = ptlrpc_queue_wait(cl, request);
- if (rc) {
- CERROR("mdc request: error in handling %d\n", rc);
- goto out;
- }
+ rc = ptlrpc_queue_wait(cl, request);
+ if (rc) {
+ CERROR("mdc request: error in handling %d\n", rc);
+ goto out;
+ }
CDEBUG(D_INODE, "mode: %o\n", request->rq_rep.mds->mode);
*req = request;
if (bulk != NULL)
OBD_FREE(bulk, sizeof(*bulk));
- return rc;
+ return rc;
}
static int request_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- int err;
- struct ptlrpc_client cl;
+ int err;
+ struct ptlrpc_client cl;
struct ptlrpc_request *request;
- ENTRY;
+ ENTRY;
- if (MINOR(inode->i_rdev) != REQUEST_MINOR) {
- EXIT;
- return -EINVAL;
- }
+ if (MINOR(inode->i_rdev) != REQUEST_MINOR) {
+ EXIT;
+ return -EINVAL;
+ }
- if ( _IOC_TYPE(cmd) != IOC_REQUEST_TYPE ||
+ if ( _IOC_TYPE(cmd) != IOC_REQUEST_TYPE ||
_IOC_NR(cmd) < IOC_REQUEST_MIN_NR ||
_IOC_NR(cmd) > IOC_REQUEST_MAX_NR ) {
CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
/* XXX complete this to get debugging working again */
err = -1;
- if (err) {
+ if (err) {
CERROR("cannot create client\n");
return -EINVAL;
}
-
- switch (cmd) {
- case IOC_REQUEST_GETATTR: {
- CERROR("-- getting attr for ino 2\n");
- err = mdc_getattr(&cl, 2, S_IFDIR, ~0, &request);
-
- CERROR("-- done err %d\n", err);
- break;
- }
-
- case IOC_REQUEST_READPAGE: {
- char *buf;
- OBD_ALLOC(buf, PAGE_SIZE);
- if (!buf) {
- err = -ENOMEM;
- break;
- }
- CERROR("-- readpage 0 for ino 2\n");
- err = mdc_readpage(&cl, 2, S_IFDIR, 0, buf, &request);
- CERROR("-- done err %d\n", err);
- OBD_FREE(buf, PAGE_SIZE);
- break;
- }
-
- case IOC_REQUEST_SETATTR: {
- struct inode inode;
- struct iattr iattr;
-
- inode.i_ino = 2;
- iattr.ia_mode = 040777;
- iattr.ia_atime = 0;
- iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
-
- err = mdc_setattr(&cl, &inode, &iattr, &request);
- CERROR("-- done err %d\n", err);
- break;
- }
-
- case IOC_REQUEST_CREATE: {
- struct inode inode;
- struct iattr iattr;
-
- inode.i_ino = 2;
- iattr.ia_mode = 040777;
- iattr.ia_atime = 0;
- iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
-
- err = mdc_create(&cl, &inode,
- "foofile", strlen("foofile"),
- NULL, 0, 0100707, 47114711,
- 11, 47, 0, &request);
- CERROR("-- done err %d\n", err);
- break;
- }
-
- default:
- err = -EINVAL;
- EXIT;
- break;
- }
- EXIT;
- return err;
+
+ switch (cmd) {
+ case IOC_REQUEST_GETATTR: {
+ CERROR("-- getting attr for ino 2\n");
+ err = mdc_getattr(&cl, 2, S_IFDIR, ~0, &request);
+
+ CERROR("-- done err %d\n", err);
+ break;
+ }
+
+ case IOC_REQUEST_READPAGE: {
+ char *buf;
+ OBD_ALLOC(buf, PAGE_SIZE);
+ if (!buf) {
+ err = -ENOMEM;
+ break;
+ }
+ CERROR("-- readpage 0 for ino 2\n");
+ err = mdc_readpage(&cl, 2, S_IFDIR, 0, buf, &request);
+ CERROR("-- done err %d\n", err);
+ OBD_FREE(buf, PAGE_SIZE);
+ break;
+ }
+
+ case IOC_REQUEST_SETATTR: {
+ struct inode inode;
+ struct iattr iattr;
+
+ inode.i_ino = 2;
+ iattr.ia_mode = 040777;
+ iattr.ia_atime = 0;
+ iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
+
+ err = mdc_setattr(&cl, &inode, &iattr, &request);
+ CERROR("-- done err %d\n", err);
+ break;
+ }
+
+ case IOC_REQUEST_CREATE: {
+ struct inode inode;
+ struct iattr iattr;
+
+ inode.i_ino = 2;
+ iattr.ia_mode = 040777;
+ iattr.ia_atime = 0;
+ iattr.ia_valid = ATTR_MODE | ATTR_ATIME;
+
+ err = mdc_create(&cl, &inode,
+ "foofile", strlen("foofile"),
+ NULL, 0, 0100707, 47114711,
+ 11, 47, 0, &request);
+ CERROR("-- done err %d\n", err);
+ break;
+ }
+
+ default:
+ err = -EINVAL;
+ EXIT;
+ break;
+ }
+ EXIT;
+ return err;
}
static struct file_operations requestdev_fops = {
- ioctl: request_ioctl,
+ ioctl: request_ioctl,
};
static struct miscdevice request_dev = {
- REQUEST_MINOR,
- "request",
- &requestdev_fops
+ REQUEST_MINOR,
+ "request",
+ &requestdev_fops
};
static int __init ptlrpc_request_init(void)
{
- misc_register(&request_dev);
+ misc_register(&request_dev);
return 0 ;
}
static void __exit ptlrpc_request_exit(void)
{
- misc_deregister(&request_dev);
+ misc_deregister(&request_dev);
}
MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
#include <linux/lustre_mds.h>
#include <linux/lustre_lib.h>
+#include <linux/lustre_net.h>
struct buffer_head *ext3_bread(void *handle, struct inode *inode,
int block, int create, int *err);
inode->i_nlink, atomic_read(&inode->i_count),
inode->i_generation,
generation);
- BUG();
+ LBUG();
iput(inode);
return ERR_PTR(-ESTALE);
}
hdr = (struct ptlreq_hdr *)req->rq_reqbuf;
- if (NTOH__u32(hdr->type) != MDS_TYPE_REQ) {
+ if (NTOH__u32(hdr->type) != PTL_RPC_REQUEST) {
CERROR("lustre_mds: wrong packet type sent %d\n",
NTOH__u32(hdr->type));
rc = -EINVAL;
mds->mds_ctxt.fs = KERNEL_DS;
mds->mds_service = ptlrpc_init_svc(64 * 1024,
- MDS_REQUEST_PORTAL,
- MDC_REPLY_PORTAL,
- "self",
- mds_unpack_req,
- mds_pack_rep,
- mds_handle);
+ MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL,
+ "self", mds_handle);
rpc_register_service(mds->mds_service, "self");
ENTRY;
- if (!(obddev->obd_flags & OBD_SET_UP))
- RETURN(0);
-
if ( !list_empty(&obddev->obd_gen_clients) ) {
CERROR("still has clients!\n");
RETURN(-EBUSY);
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* linux/mds/mds_reint.c
- *
+ *
* Lustre Metadata Server (mds) reintegration routines
- *
+ *
* Copyright (C) 2002 Cluster File Systems, Inc.
* author: Peter Braam <braam@clusterfs.com>
*
static int mds_reint_setattr(struct mds_update_record *rec, struct ptlrpc_request *req)
{
+ struct dentry *de;
struct inode *inode;
- struct dentry *de;
- de = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
+ de = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
if (IS_ERR(de) || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_SETATTR)) {
req->rq_rephdr->status = -ESTALE;
RETURN(0);
- }
+ }
inode = de->d_inode;
CDEBUG(D_INODE, "ino %ld\n", inode->i_ino);
- /* a _really_ horrible hack to avoid removing the data stored
- in the block pointers; this data is the object id
+ /* a _really_ horrible hack to avoid removing the data stored
+ in the block pointers; this data is the object id
this will go into an extended attribute at some point.
- */
- if ( rec->ur_iattr.ia_valid & ATTR_SIZE ) {
- /* ATTR_SIZE would invoke truncate: clear it */
- rec->ur_iattr.ia_valid &= ~ATTR_SIZE;
+ */
+ if ( rec->ur_iattr.ia_valid & ATTR_SIZE ) {
+ /* ATTR_SIZE would invoke truncate: clear it */
+ rec->ur_iattr.ia_valid &= ~ATTR_SIZE;
inode->i_size = rec->ur_iattr.ia_size;
/* an _even_more_ horrible hack to make this hack work with
if (!strcmp(inode->i_sb->s_type->name, "ext3"))
inode->u.ext3_i.i_disksize = inode->i_size;
- /* make sure _something_ gets set - so new inode
- goes to disk (probably won't work over XFS */
- if (!rec->ur_iattr.ia_valid & ATTR_MODE) {
- rec->ur_iattr.ia_valid |= ATTR_MODE;
- rec->ur_iattr.ia_mode = inode->i_mode;
- }
- }
+ /* make sure _something_ gets set - so new inode
+ goes to disk (probably won't work over XFS */
+ if (!rec->ur_iattr.ia_valid & ATTR_MODE) {
+ rec->ur_iattr.ia_valid |= ATTR_MODE;
+ rec->ur_iattr.ia_mode = inode->i_mode;
+ }
+ }
OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_SETATTR_WRITE);
if ( inode->i_op->setattr ) {
- req->rq_rephdr->status =
+ req->rq_rephdr->status =
inode->i_op->setattr(de, &rec->ur_iattr);
- } else {
- req->rq_rephdr->status =
+ } else {
+ req->rq_rephdr->status =
inode_setattr(inode, &rec->ur_iattr);
- }
+ }
- l_dput(de);
- EXIT;
- return 0;
+ l_dput(de);
+ RETURN(0);
}
-/*
+/*
XXX nasty hack: store the object id in the first two
- direct block spots
+ direct block spots
*/
static inline void mds_store_objid(struct inode *inode, __u64 *id)
{
/* FIXME: it is only by luck that this works on ext3 */
- memcpy(&inode->u.ext2_i.i_data, id, sizeof(*id));
+ memcpy(&inode->u.ext2_i.i_data, id, sizeof(*id));
}
-static int mds_reint_create(struct mds_update_record *rec,
- struct ptlrpc_request *req)
+static int mds_reint_create(struct mds_update_record *rec,
+ struct ptlrpc_request *req)
{
- int type = rec->ur_mode & S_IFMT;
+ int type = rec->ur_mode & S_IFMT;
struct dentry *de = NULL;
- struct mds_rep *rep = req->rq_rep.mds;
+ struct mds_rep *rep = req->rq_rep.mds;
struct dentry *dchild = NULL;
- int rc;
- ENTRY;
+ int rc;
+ ENTRY;
- de = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
+ de = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
if (IS_ERR(de) || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_CREATE)) {
- BUG();
+ LBUG();
GOTO(out_reint_create, (rc = -ESTALE));
- }
+ }
CDEBUG(D_INODE, "ino %ld\n", de->d_inode->i_ino);
- dchild = lookup_one_len(rec->ur_name, de, rec->ur_namelen - 1);
+ dchild = lookup_one_len(rec->ur_name, de, rec->ur_namelen - 1);
if (IS_ERR(dchild)) {
CERROR("child lookup error %ld\n", PTR_ERR(dchild));
- BUG();
+ LBUG();
GOTO(out_reint_create, (rc = -ESTALE));
- }
+ }
- if (dchild->d_inode) {
- CERROR("child exists (dir %ld, name %s)\n",
- de->d_inode->i_ino, rec->ur_name);
- BUG();
+ if (dchild->d_inode) {
+ CERROR("child exists (dir %ld, name %s)\n",
+ de->d_inode->i_ino, rec->ur_name);
+ LBUG();
GOTO(out_reint_create, (rc = -EEXIST));
- }
+ }
OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_CREATE_WRITE);
- switch (type) {
- case S_IFREG: {
- rc = vfs_create(de->d_inode, dchild, rec->ur_mode);
- EXIT;
- break;
- }
- case S_IFDIR: {
- rc = vfs_mkdir(de->d_inode, dchild, rec->ur_mode);
- EXIT;
- break;
- }
- case S_IFLNK: {
- rc = vfs_symlink(de->d_inode, dchild, rec->ur_tgt);
- EXIT;
- break;
- }
- case S_IFCHR:
- case S_IFBLK:
- case S_IFIFO:
- case S_IFSOCK: {
- int rdev = rec->ur_id;
- rc = vfs_mknod(de->d_inode, dchild, rec->ur_mode, rdev);
- EXIT;
- break;
- }
- }
-
- if (!rc) {
- if (type == S_IFREG)
- mds_store_objid(dchild->d_inode, &rec->ur_id);
- dchild->d_inode->i_atime = rec->ur_time;
- dchild->d_inode->i_ctime = rec->ur_time;
- dchild->d_inode->i_mtime = rec->ur_time;
- dchild->d_inode->i_uid = rec->ur_uid;
- dchild->d_inode->i_gid = rec->ur_gid;
- rep->ino = dchild->d_inode->i_ino;
- }
+ switch (type) {
+ case S_IFREG: {
+ rc = vfs_create(de->d_inode, dchild, rec->ur_mode);
+ EXIT;
+ break;
+ }
+ case S_IFDIR: {
+ rc = vfs_mkdir(de->d_inode, dchild, rec->ur_mode);
+ EXIT;
+ break;
+ }
+ case S_IFLNK: {
+ rc = vfs_symlink(de->d_inode, dchild, rec->ur_tgt);
+ EXIT;
+ break;
+ }
+ case S_IFCHR:
+ case S_IFBLK:
+ case S_IFIFO:
+ case S_IFSOCK: {
+ int rdev = rec->ur_id;
+ rc = vfs_mknod(de->d_inode, dchild, rec->ur_mode, rdev);
+ EXIT;
+ break;
+ }
+ }
+
+ if (!rc) {
+ if (type == S_IFREG)
+ mds_store_objid(dchild->d_inode, &rec->ur_id);
+ dchild->d_inode->i_atime = rec->ur_time;
+ dchild->d_inode->i_ctime = rec->ur_time;
+ dchild->d_inode->i_mtime = rec->ur_time;
+ dchild->d_inode->i_uid = rec->ur_uid;
+ dchild->d_inode->i_gid = rec->ur_gid;
+ rep->ino = dchild->d_inode->i_ino;
+ }
out_reint_create:
req->rq_rephdr->status = rc;
RETURN(0);
}
-static int mds_reint_unlink(struct mds_update_record *rec,
- struct ptlrpc_request *req)
+static int mds_reint_unlink(struct mds_update_record *rec,
+ struct ptlrpc_request *req)
{
struct dentry *de = NULL;
struct dentry *dchild = NULL;
int rc = 0;
- ENTRY;
+ ENTRY;
- de = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
+ de = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
if (IS_ERR(de) || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_UNLINK)) {
- BUG();
+ LBUG();
GOTO(out_unlink, (rc = -ESTALE));
- }
+ }
CDEBUG(D_INODE, "ino %ld\n", de->d_inode->i_ino);
- dchild = lookup_one_len(rec->ur_name, de, rec->ur_namelen - 1);
+ dchild = lookup_one_len(rec->ur_name, de, rec->ur_namelen - 1);
if (IS_ERR(dchild)) {
CERROR("child lookup error %ld\n", PTR_ERR(dchild));
- BUG();
+ LBUG();
GOTO(out_unlink, (rc = -ESTALE));
- }
+ }
- if (!dchild->d_inode) {
- CERROR("child doesn't exist (dir %ld, name %s\n",
- de->d_inode->i_ino, rec->ur_name);
- BUG();
+ if (!dchild->d_inode) {
+ CERROR("child doesn't exist (dir %ld, name %s\n",
+ de->d_inode->i_ino, rec->ur_name);
+ LBUG();
GOTO(out_unlink, (rc = -ESTALE));
- }
+ }
OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_UNLINK_WRITE);
- switch (dchild->d_inode->i_mode & S_IFMT) {
- case S_IFDIR:
- rc = vfs_rmdir(de->d_inode, dchild);
- EXIT;
- break;
- default:
+ switch (dchild->d_inode->i_mode & S_IFMT) {
+ case S_IFDIR:
+ rc = vfs_rmdir(de->d_inode, dchild);
+ EXIT;
+ break;
+ default:
rc = vfs_unlink(de->d_inode, dchild);
- EXIT;
- break;
- }
+ EXIT;
+ break;
+ }
out_unlink:
req->rq_rephdr->status = rc;
RETURN(0);
}
-static int mds_reint_link(struct mds_update_record *rec,
- struct ptlrpc_request *req)
+static int mds_reint_link(struct mds_update_record *rec,
+ struct ptlrpc_request *req)
{
struct dentry *de_src = NULL;
struct dentry *de_tgt_dir = NULL;
GOTO(out_link, (rc = -ESTALE));
}
- de_tgt_dir = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid2, NULL);
+ de_tgt_dir = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid2, NULL);
if (IS_ERR(de_tgt_dir)) {
GOTO(out_link, (rc = -ESTALE));
- }
+ }
- dchild = lookup_one_len(rec->ur_name, de_tgt_dir, rec->ur_namelen - 1);
- if (IS_ERR(dchild)) {
+ dchild = lookup_one_len(rec->ur_name, de_tgt_dir, rec->ur_namelen - 1);
+ if (IS_ERR(dchild)) {
CERROR("child lookup error %ld\n", PTR_ERR(dchild));
- GOTO(out_link, (rc = -ESTALE));
- }
+ GOTO(out_link, (rc = -ESTALE));
+ }
- if (dchild->d_inode) {
- CERROR("child exists (dir %ld, name %s\n",
- de_tgt_dir->d_inode->i_ino, rec->ur_name);
- GOTO(out_link, (rc = -EEXIST));
- }
+ if (dchild->d_inode) {
+ CERROR("child exists (dir %ld, name %s\n",
+ de_tgt_dir->d_inode->i_ino, rec->ur_name);
+ GOTO(out_link, (rc = -EEXIST));
+ }
OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_LINK_WRITE);
- rc = vfs_link(de_src, de_tgt_dir->d_inode, dchild);
+ rc = vfs_link(de_src, de_tgt_dir->d_inode, dchild);
EXIT;
out_link:
- req->rq_rephdr->status = rc;
- l_dput(de_src);
- l_dput(de_tgt_dir);
- l_dput(dchild);
- return 0;
+ req->rq_rephdr->status = rc;
+ l_dput(de_src);
+ l_dput(de_tgt_dir);
+ l_dput(dchild);
+ return 0;
}
-static int mds_reint_rename(struct mds_update_record *rec,
- struct ptlrpc_request *req)
+static int mds_reint_rename(struct mds_update_record *rec,
+ struct ptlrpc_request *req)
{
- struct dentry *de_srcdir = NULL;
- struct dentry *de_tgtdir = NULL;
- struct dentry *de_old = NULL;
- struct dentry *de_new = NULL;
- int rc = 0;
- ENTRY;
-
- de_srcdir = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
+ struct dentry *de_srcdir = NULL;
+ struct dentry *de_tgtdir = NULL;
+ struct dentry *de_old = NULL;
+ struct dentry *de_new = NULL;
+ int rc = 0;
+ ENTRY;
+
+ de_srcdir = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid1, NULL);
if (IS_ERR(de_srcdir)) {
GOTO(out_rename, (rc = -ESTALE));
- }
+ }
- de_tgtdir = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid2, NULL);
+ de_tgtdir = mds_fid2dentry(&req->rq_obd->u.mds, rec->ur_fid2, NULL);
if (IS_ERR(de_tgtdir)) {
GOTO(out_rename, (rc = -ESTALE));
- }
+ }
- de_old = lookup_one_len(rec->ur_name, de_srcdir, rec->ur_namelen - 1);
+ de_old = lookup_one_len(rec->ur_name, de_srcdir, rec->ur_namelen - 1);
if (IS_ERR(de_old)) {
CERROR("child lookup error %ld\n", PTR_ERR(de_old));
GOTO(out_rename, (rc = -ESTALE));
- }
+ }
- de_new = lookup_one_len(rec->ur_tgt, de_tgtdir, rec->ur_tgtlen - 1);
+ de_new = lookup_one_len(rec->ur_tgt, de_tgtdir, rec->ur_tgtlen - 1);
if (IS_ERR(de_new)) {
CERROR("child lookup error %ld\n", PTR_ERR(de_new));
GOTO(out_rename, (rc = -ESTALE));
- }
+ }
OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_RENAME_WRITE);
- rc = vfs_rename(de_srcdir->d_inode, de_old, de_tgtdir->d_inode, de_new);
+ rc = vfs_rename(de_srcdir->d_inode, de_old, de_tgtdir->d_inode, de_new);
EXIT;
out_rename:
- req->rq_rephdr->status = rc;
- l_dput(de_new);
- l_dput(de_old);
- l_dput(de_tgtdir);
- l_dput(de_srcdir);
- return 0;
+ req->rq_rephdr->status = rc;
+ l_dput(de_new);
+ l_dput(de_old);
+ l_dput(de_tgtdir);
+ l_dput(de_srcdir);
+ return 0;
}
-typedef int (*mds_reinter)(struct mds_update_record *, struct ptlrpc_request*);
+typedef int (*mds_reinter)(struct mds_update_record *, struct ptlrpc_request*);
static mds_reinter reinters[REINT_MAX+1] = {
[REINT_SETATTR] mds_reint_setattr,
int mds_reint_rec(struct mds_update_record *rec, struct ptlrpc_request *req)
{
- int rc;
+ int rc;
if (rec->ur_opcode < 0 || rec->ur_opcode > REINT_MAX) {
CERROR("opcode %d not valid\n", rec->ur_opcode);
rc = req->rq_status = -EINVAL;
RETURN(rc);
- }
+ }
- rc = mds_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
- &req->rq_replen, &req->rq_repbuf);
+ rc = mds_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
+ &req->rq_replen, &req->rq_repbuf);
if (rc) {
CERROR("mds: out of memory\n");
rc = req->rq_status = -ENOMEM;
RETURN(rc);
- }
- req->rq_rephdr->xid = req->rq_reqhdr->xid;
-
- rc = reinters[rec->ur_opcode](rec, req);
- return rc;
-}
+ }
+ req->rq_rephdr->xid = req->rq_reqhdr->xid;
+ rc = reinters[rec->ur_opcode](rec, req);
+ return rc;
+}
int waitfor_one_page(struct page *page)
{
- int error = 0;
- struct buffer_head *bh, *head = page->buffers;
-
- bh = head;
- do {
- wait_on_buffer(bh);
- if (buffer_req(bh) && !buffer_uptodate(bh))
- error = -EIO;
- } while ((bh = bh->b_this_page) != head);
- return error;
+ int error = 0;
+ struct buffer_head *bh, *head = page->buffers;
+
+ bh = head;
+ do {
+ wait_on_buffer(bh);
+ if (buffer_req(bh) && !buffer_uptodate(bh))
+ error = -EIO;
+ } while ((bh = bh->b_this_page) != head);
+ return error;
}
/*
*/
static inline unsigned ext2_chunk_size(struct inode *inode)
{
- //return inode->i_sb->s_blocksize;
- return PAGE_SIZE;
+ //return inode->i_sb->s_blocksize;
+ return PAGE_SIZE;
}
static inline void ext2_put_page(struct page *page)
{
- kunmap(page);
- page_cache_release(page);
+ kunmap(page);
+ page_cache_release(page);
}
static inline unsigned long dir_pages(struct inode *inode)
{
- return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
+ return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
}
static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to)
{
- struct inode *dir = page->mapping->host;
- int err = 0;
- dir->i_version = ++event;
- page->mapping->a_ops->commit_write(NULL, page, from, to);
- if (IS_SYNC(dir))
- err = waitfor_one_page(page);
- return err;
+ struct inode *dir = page->mapping->host;
+ int err = 0;
+ dir->i_version = ++event;
+ page->mapping->a_ops->commit_write(NULL, page, from, to);
+ if (IS_SYNC(dir))
+ err = waitfor_one_page(page);
+ return err;
}
static void ext2_check_page(struct page *page)
{
- struct inode *dir = page->mapping->host;
- unsigned chunk_size = ext2_chunk_size(dir);
- char *kaddr = page_address(page);
- // u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
- unsigned offs, rec_len;
- unsigned limit = PAGE_CACHE_SIZE;
- ext2_dirent *p;
- char *error;
-
- if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
- limit = dir->i_size & ~PAGE_CACHE_MASK;
- if (limit & (chunk_size - 1))
- goto Ebadsize;
- for (offs = limit; offs<PAGE_CACHE_SIZE; offs += chunk_size) {
- ext2_dirent *p = (ext2_dirent*)(kaddr + offs);
- p->rec_len = cpu_to_le16(chunk_size);
- }
- if (!limit)
- goto out;
- }
- for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
- p = (ext2_dirent *)(kaddr + offs);
- rec_len = le16_to_cpu(p->rec_len);
-
- if (rec_len < EXT2_DIR_REC_LEN(1))
- goto Eshort;
- if (rec_len & 3)
- goto Ealign;
- if (rec_len < EXT2_DIR_REC_LEN(p->name_len))
- goto Enamelen;
- if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
- goto Espan;
- // if (le32_to_cpu(p->inode) > max_inumber)
- //goto Einumber;
- }
- if (offs != limit)
- goto Eend;
+ struct inode *dir = page->mapping->host;
+ unsigned chunk_size = ext2_chunk_size(dir);
+ char *kaddr = page_address(page);
+ // u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
+ unsigned offs, rec_len;
+ unsigned limit = PAGE_CACHE_SIZE;
+ ext2_dirent *p;
+ char *error;
+
+ if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
+ limit = dir->i_size & ~PAGE_CACHE_MASK;
+ if (limit & (chunk_size - 1))
+ goto Ebadsize;
+ for (offs = limit; offs<PAGE_CACHE_SIZE; offs += chunk_size) {
+ ext2_dirent *p = (ext2_dirent*)(kaddr + offs);
+ p->rec_len = cpu_to_le16(chunk_size);
+ }
+ if (!limit)
+ goto out;
+ }
+ for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
+ p = (ext2_dirent *)(kaddr + offs);
+ rec_len = le16_to_cpu(p->rec_len);
+
+ if (rec_len < EXT2_DIR_REC_LEN(1))
+ goto Eshort;
+ if (rec_len & 3)
+ goto Ealign;
+ if (rec_len < EXT2_DIR_REC_LEN(p->name_len))
+ goto Enamelen;
+ if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
+ goto Espan;
+ // if (le32_to_cpu(p->inode) > max_inumber)
+ //goto Einumber;
+ }
+ if (offs != limit)
+ goto Eend;
out:
- SetPageChecked(page);
- return;
+ SetPageChecked(page);
+ return;
- /* Too bad, we had an error */
+ /* Too bad, we had an error */
Ebadsize:
- CERROR("ext2_check_page"
- "size of directory #%lu is not a multiple of chunk size",
- dir->i_ino
- );
- goto fail;
+ CERROR("ext2_check_page"
+ "size of directory #%lu is not a multiple of chunk size",
+ dir->i_ino
+ );
+ goto fail;
Eshort:
- error = "rec_len is smaller than minimal";
- goto bad_entry;
+ error = "rec_len is smaller than minimal";
+ goto bad_entry;
Ealign:
- error = "unaligned directory entry";
- goto bad_entry;
+ error = "unaligned directory entry";
+ goto bad_entry;
Enamelen:
- error = "rec_len is too small for name_len";
- goto bad_entry;
+ error = "rec_len is too small for name_len";
+ goto bad_entry;
Espan:
- error = "directory entry across blocks";
- goto bad_entry;
- //Einumber:
- // error = "inode out of bounds";
+ error = "directory entry across blocks";
+ goto bad_entry;
+ //Einumber:
+ // error = "inode out of bounds";
bad_entry:
- CERROR("ext2_check_page" "bad entry in directory #%lu: %s - "
- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
- dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
- (unsigned long) le32_to_cpu(p->inode),
- rec_len, p->name_len);
- goto fail;
+ CERROR("ext2_check_page" "bad entry in directory #%lu: %s - "
+ "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+ dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ (unsigned long) le32_to_cpu(p->inode),
+ rec_len, p->name_len);
+ goto fail;
Eend:
- p = (ext2_dirent *)(kaddr + offs);
- CERROR("ext2_check_page"
- "entry in directory #%lu spans the page boundary"
- "offset=%lu, inode=%lu",
- dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
- (unsigned long) le32_to_cpu(p->inode));
+ p = (ext2_dirent *)(kaddr + offs);
+ CERROR("ext2_check_page"
+ "entry in directory #%lu spans the page boundary"
+ "offset=%lu, inode=%lu",
+ dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ (unsigned long) le32_to_cpu(p->inode));
fail:
- SetPageChecked(page);
- SetPageError(page);
+ SetPageChecked(page);
+ SetPageError(page);
}
static struct page * ext2_get_page(struct inode *dir, unsigned long n)
{
- struct address_space *mapping = dir->i_mapping;
- struct page *page = read_cache_page(mapping, n,
- (filler_t*)mapping->a_ops->readpage, NULL);
- if (!IS_ERR(page)) {
- wait_on_page(page);
- kmap(page);
- if (!Page_Uptodate(page))
- goto fail;
- if (!PageChecked(page))
- ext2_check_page(page);
- if (PageError(page))
- goto fail;
- }
- return page;
+ struct address_space *mapping = dir->i_mapping;
+ struct page *page = read_cache_page(mapping, n,
+ (filler_t*)mapping->a_ops->readpage, NULL);
+ if (!IS_ERR(page)) {
+ wait_on_page(page);
+ kmap(page);
+ if (!Page_Uptodate(page))
+ goto fail;
+ if (!PageChecked(page))
+ ext2_check_page(page);
+ if (PageError(page))
+ goto fail;
+ }
+ return page;
fail:
- ext2_put_page(page);
- return ERR_PTR(-EIO);
+ ext2_put_page(page);
+ return ERR_PTR(-EIO);
}
/*
* len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller.
*/
static inline int ext2_match (int len, const char * const name,
- struct ext2_dir_entry_2 * de)
+ struct ext2_dir_entry_2 * de)
{
- if (len != de->name_len)
- return 0;
- if (!de->inode)
- return 0;
- return !memcmp(name, de->name, len);
+ if (len != de->name_len)
+ return 0;
+ if (!de->inode)
+ return 0;
+ return !memcmp(name, de->name, len);
}
/*
*/
static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
{
- return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
+ return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
}
static inline unsigned
ext2_validate_entry(char *base, unsigned offset, unsigned mask)
{
- ext2_dirent *de = (ext2_dirent*)(base + offset);
- ext2_dirent *p = (ext2_dirent*)(base + (offset&mask));
- while ((char*)p < (char*)de)
- p = ext2_next_entry(p);
- return (char *)p - base;
+ ext2_dirent *de = (ext2_dirent*)(base + offset);
+ ext2_dirent *p = (ext2_dirent*)(base + (offset&mask));
+ while ((char*)p < (char*)de)
+ p = ext2_next_entry(p);
+ return (char *)p - base;
}
static unsigned char ext2_filetype_table[EXT2_FT_MAX] = {
- [EXT2_FT_UNKNOWN] DT_UNKNOWN,
- [EXT2_FT_REG_FILE] DT_REG,
- [EXT2_FT_DIR] DT_DIR,
- [EXT2_FT_CHRDEV] DT_CHR,
- [EXT2_FT_BLKDEV] DT_BLK,
- [EXT2_FT_FIFO] DT_FIFO,
- [EXT2_FT_SOCK] DT_SOCK,
- [EXT2_FT_SYMLINK] DT_LNK,
+ [EXT2_FT_UNKNOWN] DT_UNKNOWN,
+ [EXT2_FT_REG_FILE] DT_REG,
+ [EXT2_FT_DIR] DT_DIR,
+ [EXT2_FT_CHRDEV] DT_CHR,
+ [EXT2_FT_BLKDEV] DT_BLK,
+ [EXT2_FT_FIFO] DT_FIFO,
+ [EXT2_FT_SOCK] DT_SOCK,
+ [EXT2_FT_SYMLINK] DT_LNK,
};
static unsigned int obdfs_dt2fmt[DT_WHT + 1] = {
- [EXT2_FT_UNKNOWN] 0,
- [EXT2_FT_REG_FILE] S_IFREG,
- [EXT2_FT_DIR] S_IFDIR,
- [EXT2_FT_CHRDEV] S_IFCHR,
- [EXT2_FT_BLKDEV] S_IFBLK,
- [EXT2_FT_FIFO] S_IFIFO,
- [EXT2_FT_SOCK] S_IFSOCK,
- [EXT2_FT_SYMLINK] S_IFLNK
+ [EXT2_FT_UNKNOWN] 0,
+ [EXT2_FT_REG_FILE] S_IFREG,
+ [EXT2_FT_DIR] S_IFDIR,
+ [EXT2_FT_CHRDEV] S_IFCHR,
+ [EXT2_FT_BLKDEV] S_IFBLK,
+ [EXT2_FT_FIFO] S_IFIFO,
+ [EXT2_FT_SOCK] S_IFSOCK,
+ [EXT2_FT_SYMLINK] S_IFLNK
};
-
+
#define S_SHIFT 12
static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = {
- [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE,
- [S_IFDIR >> S_SHIFT] EXT2_FT_DIR,
- [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV,
- [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV,
- [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO,
- [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK,
- [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK,
+ [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE,
+ [S_IFDIR >> S_SHIFT] EXT2_FT_DIR,
+ [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV,
+ [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV,
+ [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO,
+ [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK,
+ [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK,
};
static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)
{
- mode_t mode = inode->i_mode;
- de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+ mode_t mode = inode->i_mode;
+ de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
}
int
new_obdfs_readdir (struct file * filp, void * dirent, filldir_t filldir)
{
- loff_t pos = filp->f_pos;
- struct inode *inode = filp->f_dentry->d_inode;
- // XXX struct super_block *sb = inode->i_sb;
- unsigned offset = pos & ~PAGE_CACHE_MASK;
- unsigned long n = pos >> PAGE_CACHE_SHIFT;
- unsigned long npages = dir_pages(inode);
- unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
- unsigned char *types = NULL;
- int need_revalidate = (filp->f_version != inode->i_version);
-
- if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
- goto done;
-
- types = ext2_filetype_table;
-
- for ( ; n < npages; n++, offset = 0) {
- char *kaddr, *limit;
- ext2_dirent *de;
- struct page *page = ext2_get_page(inode, n);
-
- if (IS_ERR(page))
- continue;
- kaddr = page_address(page);
- if (need_revalidate) {
- offset = ext2_validate_entry(kaddr, offset, chunk_mask);
- need_revalidate = 0;
- }
- de = (ext2_dirent *)(kaddr+offset);
- limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1);
- for ( ;(char*)de <= limit; de = ext2_next_entry(de))
- if (de->inode) {
- int over;
- unsigned char d_type = DT_UNKNOWN;
-
- if (types && de->file_type < EXT2_FT_MAX)
- d_type = types[de->file_type];
-
- offset = (char *)de - kaddr;
- over = filldir(dirent, de->name, de->name_len,
- (n<<PAGE_CACHE_SHIFT) | offset,
- le32_to_cpu(de->inode), d_type);
- if (over) {
- ext2_put_page(page);
- goto done;
- }
- }
- ext2_put_page(page);
- }
+ loff_t pos = filp->f_pos;
+ struct inode *inode = filp->f_dentry->d_inode;
+ // XXX struct super_block *sb = inode->i_sb;
+ unsigned offset = pos & ~PAGE_CACHE_MASK;
+ unsigned long n = pos >> PAGE_CACHE_SHIFT;
+ unsigned long npages = dir_pages(inode);
+ unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
+ unsigned char *types = NULL;
+ int need_revalidate = (filp->f_version != inode->i_version);
+
+ if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
+ goto done;
+
+ types = ext2_filetype_table;
+
+ for ( ; n < npages; n++, offset = 0) {
+ char *kaddr, *limit;
+ ext2_dirent *de;
+ struct page *page = ext2_get_page(inode, n);
+
+ if (IS_ERR(page))
+ continue;
+ kaddr = page_address(page);
+ if (need_revalidate) {
+ offset = ext2_validate_entry(kaddr, offset, chunk_mask);
+ need_revalidate = 0;
+ }
+ de = (ext2_dirent *)(kaddr+offset);
+ limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1);
+ for ( ;(char*)de <= limit; de = ext2_next_entry(de))
+ if (de->inode) {
+ int over;
+ unsigned char d_type = DT_UNKNOWN;
+
+ if (types && de->file_type < EXT2_FT_MAX)
+ d_type = types[de->file_type];
+
+ offset = (char *)de - kaddr;
+ over = filldir(dirent, de->name, de->name_len,
+ (n<<PAGE_CACHE_SHIFT) | offset,
+ le32_to_cpu(de->inode), d_type);
+ if (over) {
+ ext2_put_page(page);
+ goto done;
+ }
+ }
+ ext2_put_page(page);
+ }
done:
- filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
- filp->f_version = inode->i_version;
- UPDATE_ATIME(inode);
- return 0;
+ filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
+ filp->f_version = inode->i_version;
+ UPDATE_ATIME(inode);
+ return 0;
}
/*
- * ext2_find_entry()
+ * ext2_find_entry()
*
* finds an entry in the specified directory with the wanted name. It
* returns the page in which the entry was found, and the entry itself
* Entry is guaranteed to be valid.
*/
struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
- struct dentry *dentry, struct page ** res_page)
+ struct dentry *dentry, struct page ** res_page)
{
- const char *name = dentry->d_name.name;
- int namelen = dentry->d_name.len;
- unsigned reclen = EXT2_DIR_REC_LEN(namelen);
- unsigned long start, n;
- unsigned long npages = dir_pages(dir);
- struct page *page = NULL;
- ext2_dirent * de;
-
- /* OFFSET_CACHE */
- *res_page = NULL;
-
- // start = dir->u.ext2_i.i_dir_start_lookup;
- start = 0;
- if (start >= npages)
- start = 0;
- n = start;
- do {
- char *kaddr;
- page = ext2_get_page(dir, n);
- if (!IS_ERR(page)) {
- kaddr = page_address(page);
- de = (ext2_dirent *) kaddr;
- kaddr += PAGE_CACHE_SIZE - reclen;
- while ((char *) de <= kaddr) {
- if (ext2_match (namelen, name, de))
- goto found;
- de = ext2_next_entry(de);
- }
- ext2_put_page(page);
- }
- if (++n >= npages)
- n = 0;
- } while (n != start);
- return NULL;
+ const char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ unsigned reclen = EXT2_DIR_REC_LEN(namelen);
+ unsigned long start, n;
+ unsigned long npages = dir_pages(dir);
+ struct page *page = NULL;
+ ext2_dirent * de;
+
+ /* OFFSET_CACHE */
+ *res_page = NULL;
+
+ // start = dir->u.ext2_i.i_dir_start_lookup;
+ start = 0;
+ if (start >= npages)
+ start = 0;
+ n = start;
+ do {
+ char *kaddr;
+ page = ext2_get_page(dir, n);
+ if (!IS_ERR(page)) {
+ kaddr = page_address(page);
+ de = (ext2_dirent *) kaddr;
+ kaddr += PAGE_CACHE_SIZE - reclen;
+ while ((char *) de <= kaddr) {
+ if (ext2_match (namelen, name, de))
+ goto found;
+ de = ext2_next_entry(de);
+ }
+ ext2_put_page(page);
+ }
+ if (++n >= npages)
+ n = 0;
+ } while (n != start);
+ return NULL;
found:
- *res_page = page;
- // dir->u.ext2_i.i_dir_start_lookup = n;
- return de;
+ *res_page = page;
+ // dir->u.ext2_i.i_dir_start_lookup = n;
+ return de;
}
struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
{
- struct page *page = ext2_get_page(dir, 0);
- ext2_dirent *de = NULL;
-
- if (!IS_ERR(page)) {
- de = ext2_next_entry((ext2_dirent *) page_address(page));
- *p = page;
- }
- return de;
+ struct page *page = ext2_get_page(dir, 0);
+ ext2_dirent *de = NULL;
+
+ if (!IS_ERR(page)) {
+ de = ext2_next_entry((ext2_dirent *) page_address(page));
+ *p = page;
+ }
+ return de;
}
ino_t obdfs_inode_by_name(struct inode * dir, struct dentry *dentry, int *type)
{
- ino_t res = 0;
- struct ext2_dir_entry_2 * de;
- struct page *page;
-
- de = ext2_find_entry (dir, dentry, &page);
- if (de) {
- res = le32_to_cpu(de->inode);
- *type = obdfs_dt2fmt[de->file_type];
- kunmap(page);
- page_cache_release(page);
- }
- return res;
+ ino_t res = 0;
+ struct ext2_dir_entry_2 * de;
+ struct page *page;
+
+ de = ext2_find_entry (dir, dentry, &page);
+ if (de) {
+ res = le32_to_cpu(de->inode);
+ *type = obdfs_dt2fmt[de->file_type];
+ kunmap(page);
+ page_cache_release(page);
+ }
+ return res;
}
/* Releases the page */
void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
- struct page *page, struct inode *inode)
+ struct page *page, struct inode *inode)
{
- unsigned from = (char *) de - (char *) page_address(page);
- unsigned to = from + le16_to_cpu(de->rec_len);
- int err;
-
- lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- BUG();
- de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- err = ext2_commit_chunk(page, from, to);
- UnlockPage(page);
- ext2_put_page(page);
+ unsigned from = (char *) de - (char *) page_address(page);
+ unsigned to = from + le16_to_cpu(de->rec_len);
+ int err;
+
+ lock_page(page);
+ err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ if (err)
+ LBUG();
+ de->inode = cpu_to_le32(inode->i_ino);
+ ext2_set_de_type (de, inode);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ err = ext2_commit_chunk(page, from, to);
+ UnlockPage(page);
+ ext2_put_page(page);
}
/*
- * Parent is locked.
+ * Parent is locked.
*/
int ext2_add_link (struct dentry *dentry, struct inode *inode)
{
- struct inode *dir = dentry->d_parent->d_inode;
- const char *name = dentry->d_name.name;
- int namelen = dentry->d_name.len;
- unsigned reclen = EXT2_DIR_REC_LEN(namelen);
- unsigned short rec_len, name_len;
- struct page *page = NULL;
- ext2_dirent * de;
- unsigned long npages = dir_pages(dir);
- unsigned long n;
- char *kaddr;
- unsigned from, to;
- int err;
-
- /* We take care of directory expansion in the same loop */
- for (n = 0; n <= npages; n++) {
- page = ext2_get_page(dir, n);
- err = PTR_ERR(page);
- if (IS_ERR(page))
- goto out;
- kaddr = page_address(page);
- de = (ext2_dirent *)kaddr;
- kaddr += PAGE_CACHE_SIZE - reclen;
- while ((char *)de <= kaddr) {
- err = -EEXIST;
- if (ext2_match (namelen, name, de))
- goto out_page;
- name_len = EXT2_DIR_REC_LEN(de->name_len);
- rec_len = le16_to_cpu(de->rec_len);
- if ( n==npages && rec_len == 0) {
- CERROR("Fatal dir behaviour\n");
- goto out_page;
- }
- if (!de->inode && rec_len >= reclen)
- goto got_it;
- if (rec_len >= name_len + reclen)
- goto got_it;
- de = (ext2_dirent *) ((char *) de + rec_len);
- }
- ext2_put_page(page);
- }
- BUG();
- return -EINVAL;
+ struct inode *dir = dentry->d_parent->d_inode;
+ const char *name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ unsigned reclen = EXT2_DIR_REC_LEN(namelen);
+ unsigned short rec_len, name_len;
+ struct page *page = NULL;
+ ext2_dirent * de;
+ unsigned long npages = dir_pages(dir);
+ unsigned long n;
+ char *kaddr;
+ unsigned from, to;
+ int err;
+
+ /* We take care of directory expansion in the same loop */
+ for (n = 0; n <= npages; n++) {
+ page = ext2_get_page(dir, n);
+ err = PTR_ERR(page);
+ if (IS_ERR(page))
+ goto out;
+ kaddr = page_address(page);
+ de = (ext2_dirent *)kaddr;
+ kaddr += PAGE_CACHE_SIZE - reclen;
+ while ((char *)de <= kaddr) {
+ err = -EEXIST;
+ if (ext2_match (namelen, name, de))
+ goto out_page;
+ name_len = EXT2_DIR_REC_LEN(de->name_len);
+ rec_len = le16_to_cpu(de->rec_len);
+ if ( n==npages && rec_len == 0) {
+ CERROR("Fatal dir behaviour\n");
+ goto out_page;
+ }
+ if (!de->inode && rec_len >= reclen)
+ goto got_it;
+ if (rec_len >= name_len + reclen)
+ goto got_it;
+ de = (ext2_dirent *) ((char *) de + rec_len);
+ }
+ ext2_put_page(page);
+ }
+ LBUG();
+ return -EINVAL;
got_it:
- from = (char*)de - (char*)page_address(page);
- to = from + rec_len;
- lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- goto out_unlock;
- if (de->inode) {
- ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
- de1->rec_len = cpu_to_le16(rec_len - name_len);
- de->rec_len = cpu_to_le16(name_len);
- de = de1;
- }
- de->name_len = namelen;
- memcpy (de->name, name, namelen);
- de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
- CDEBUG(D_INODE, "type set to %o\n", de->file_type);
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- err = ext2_commit_chunk(page, from, to);
-
- // change_inode happens with the commit_chunk
+ from = (char*)de - (char*)page_address(page);
+ to = from + rec_len;
+ lock_page(page);
+ err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ if (err)
+ goto out_unlock;
+ if (de->inode) {
+ ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
+ de1->rec_len = cpu_to_le16(rec_len - name_len);
+ de->rec_len = cpu_to_le16(name_len);
+ de = de1;
+ }
+ de->name_len = namelen;
+ memcpy (de->name, name, namelen);
+ de->inode = cpu_to_le32(inode->i_ino);
+ ext2_set_de_type (de, inode);
+ CDEBUG(D_INODE, "type set to %o\n", de->file_type);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ err = ext2_commit_chunk(page, from, to);
+
+ // change_inode happens with the commit_chunk
// obdfs_change_inode(dir);
- /* OFFSET_CACHE */
+ /* OFFSET_CACHE */
out_unlock:
- UnlockPage(page);
+ UnlockPage(page);
out_page:
- ext2_put_page(page);
+ ext2_put_page(page);
out:
- return err;
+ return err;
}
/*
*/
int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
{
- struct address_space *mapping = page->mapping;
- struct inode *inode = mapping->host;
- char *kaddr = page_address(page);
- unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
- unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
- ext2_dirent * pde = NULL;
- ext2_dirent * de = (ext2_dirent *) (kaddr + from);
- int err;
-
- while ((char*)de < (char*)dir) {
- pde = de;
- de = ext2_next_entry(de);
- }
- if (pde)
- from = (char*)pde - (char*)page_address(page);
- lock_page(page);
- err = mapping->a_ops->prepare_write(NULL, page, from, to);
- if (err)
- BUG();
- if (pde)
- pde->rec_len = cpu_to_le16(to-from);
- dir->inode = 0;
- inode->i_ctime = inode->i_mtime = CURRENT_TIME;
- err = ext2_commit_chunk(page, from, to);
- UnlockPage(page);
- ext2_put_page(page);
- return err;
+ struct address_space *mapping = page->mapping;
+ struct inode *inode = mapping->host;
+ char *kaddr = page_address(page);
+ unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
+ unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
+ ext2_dirent * pde = NULL;
+ ext2_dirent * de = (ext2_dirent *) (kaddr + from);
+ int err;
+
+ while ((char*)de < (char*)dir) {
+ pde = de;
+ de = ext2_next_entry(de);
+ }
+ if (pde)
+ from = (char*)pde - (char*)page_address(page);
+ lock_page(page);
+ err = mapping->a_ops->prepare_write(NULL, page, from, to);
+ if (err)
+ LBUG();
+ if (pde)
+ pde->rec_len = cpu_to_le16(to-from);
+ dir->inode = 0;
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+ err = ext2_commit_chunk(page, from, to);
+ UnlockPage(page);
+ ext2_put_page(page);
+ return err;
}
/*
*/
int ext2_make_empty(struct inode *inode, struct inode *parent)
{
- struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
- unsigned chunk_size = ext2_chunk_size(inode);
- struct ext2_dir_entry_2 * de;
- char *base;
- int err;
- ENTRY;
-
- if (!page)
- return -ENOMEM;
- err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
- if (err)
- goto fail;
-
- base = page_address(page);
-
- de = (struct ext2_dir_entry_2 *) base;
- de->name_len = 1;
- de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
- memcpy (de->name, ".\0\0", 4);
- de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
-
- de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1));
- de->name_len = 2;
- de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
- de->inode = cpu_to_le32(parent->i_ino);
- memcpy (de->name, "..\0", 4);
- ext2_set_de_type (de, inode);
-
- err = ext2_commit_chunk(page, 0, chunk_size);
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page = grab_cache_page(mapping, 0);
+ unsigned chunk_size = ext2_chunk_size(inode);
+ struct ext2_dir_entry_2 * de;
+ char *base;
+ int err;
+ ENTRY;
+
+ if (!page)
+ return -ENOMEM;
+ err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
+ if (err)
+ goto fail;
+
+ base = page_address(page);
+
+ de = (struct ext2_dir_entry_2 *) base;
+ de->name_len = 1;
+ de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
+ memcpy (de->name, ".\0\0", 4);
+ de->inode = cpu_to_le32(inode->i_ino);
+ ext2_set_de_type (de, inode);
+
+ de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1));
+ de->name_len = 2;
+ de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
+ de->inode = cpu_to_le32(parent->i_ino);
+ memcpy (de->name, "..\0", 4);
+ ext2_set_de_type (de, inode);
+
+ err = ext2_commit_chunk(page, 0, chunk_size);
fail:
- UnlockPage(page);
- page_cache_release(page);
- ENTRY;
- return err;
+ UnlockPage(page);
+ page_cache_release(page);
+ ENTRY;
+ return err;
}
/*
*/
int ext2_empty_dir (struct inode * inode)
{
- struct page *page = NULL;
- unsigned long i, npages = dir_pages(inode);
-
- for (i = 0; i < npages; i++) {
- char *kaddr;
- ext2_dirent * de;
- page = ext2_get_page(inode, i);
-
- if (IS_ERR(page))
- continue;
-
- kaddr = page_address(page);
- de = (ext2_dirent *)kaddr;
- kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1);
-
- while ((char *)de <= kaddr) {
- if (de->inode != 0) {
- /* check for . and .. */
- if (de->name[0] != '.')
- goto not_empty;
- if (de->name_len > 2)
- goto not_empty;
- if (de->name_len < 2) {
- if (de->inode !=
- cpu_to_le32(inode->i_ino))
- goto not_empty;
- } else if (de->name[1] != '.')
- goto not_empty;
- }
- de = ext2_next_entry(de);
- }
- ext2_put_page(page);
- }
- return 1;
+ struct page *page = NULL;
+ unsigned long i, npages = dir_pages(inode);
+
+ for (i = 0; i < npages; i++) {
+ char *kaddr;
+ ext2_dirent * de;
+ page = ext2_get_page(inode, i);
+
+ if (IS_ERR(page))
+ continue;
+
+ kaddr = page_address(page);
+ de = (ext2_dirent *)kaddr;
+ kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1);
+
+ while ((char *)de <= kaddr) {
+ if (de->inode != 0) {
+ /* check for . and .. */
+ if (de->name[0] != '.')
+ goto not_empty;
+ if (de->name_len > 2)
+ goto not_empty;
+ if (de->name_len < 2) {
+ if (de->inode !=
+ cpu_to_le32(inode->i_ino))
+ goto not_empty;
+ } else if (de->name[1] != '.')
+ goto not_empty;
+ }
+ de = ext2_next_entry(de);
+ }
+ ext2_put_page(page);
+ }
+ return 1;
not_empty:
- ext2_put_page(page);
- return 0;
+ ext2_put_page(page);
+ return 0;
}
struct file_operations obdfs_dir_operations = {
*/
void __set_page_clean(struct page *page)
{
- struct address_space *mapping = page->mapping;
- struct inode *inode;
-
- if (!mapping)
- return;
-
- list_del(&page->list);
- list_add(&page->list, &mapping->clean_pages);
-
- inode = mapping->host;
- if (list_empty(&mapping->dirty_pages)) {
- CDEBUG(D_INODE, "inode clean\n");
- inode->i_state &= ~I_DIRTY_PAGES;
- }
- EXIT;
+ struct address_space *mapping = page->mapping;
+ struct inode *inode;
+
+ if (!mapping)
+ return;
+
+ list_del(&page->list);
+ list_add(&page->list, &mapping->clean_pages);
+
+ inode = mapping->host;
+ if (list_empty(&mapping->dirty_pages)) {
+ CDEBUG(D_INODE, "inode clean\n");
+ inode->i_state &= ~I_DIRTY_PAGES;
+ }
+ EXIT;
}
#else
*/
void set_page_dirty(struct page *page)
{
- if (!test_and_set_bit(PG_dirty, &page->flags)) {
- struct address_space *mapping = page->mapping;
-
- if (mapping) {
- spin_lock(&pagecache_lock);
- list_del(&page->list);
- list_add(&page->list, &mapping->dirty_pages);
- spin_unlock(&pagecache_lock);
-
- if (mapping->host)
- mark_inode_dirty_pages(mapping->host);
- }
- }
+ if (!test_and_set_bit(PG_dirty, &page->flags)) {
+ struct address_space *mapping = page->mapping;
+
+ if (mapping) {
+ spin_lock(&pagecache_lock);
+ list_del(&page->list);
+ list_add(&page->list, &mapping->dirty_pages);
+ spin_unlock(&pagecache_lock);
+
+ if (mapping->host)
+ mark_inode_dirty_pages(mapping->host);
+ }
+ }
}
/*
* Remove page from dirty list
*/
void __set_page_clean(struct page *page)
{
- struct address_space *mapping = page->mapping;
- struct inode *inode;
-
- if (!mapping)
- return;
-
- spin_lock(&pagecache_lock);
- list_del(&page->list);
- list_add(&page->list, &mapping->clean_pages);
-
- inode = mapping->host;
- if (list_empty(&mapping->dirty_pages)) {
- CDEBUG(D_INODE, "inode clean\n");
- inode->i_state &= ~I_DIRTY_PAGES;
- }
- spin_unlock(&pagecache_lock);
- EXIT;
+ struct address_space *mapping = page->mapping;
+ struct inode *inode;
+
+ if (!mapping)
+ return;
+
+ spin_lock(&pagecache_lock);
+ list_del(&page->list);
+ list_add(&page->list, &mapping->clean_pages);
+
+ inode = mapping->host;
+ if (list_empty(&mapping->dirty_pages)) {
+ CDEBUG(D_INODE, "inode clean\n");
+ inode->i_state &= ~I_DIRTY_PAGES;
+ }
+ spin_unlock(&pagecache_lock);
+ EXIT;
}
#endif
inline void set_page_clean(struct page *page)
{
- if (PageDirty(page)) {
- ClearPageDirty(page);
- __set_page_clean(page);
- }
+ if (PageDirty(page)) {
+ ClearPageDirty(page);
+ __set_page_clean(page);
+ }
}
/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */
EXIT;
return -ENOMEM;
}
- oa->o_valid = OBD_MD_FLNOTOBD;
+ oa->o_valid = OBD_MD_FLNOTOBD;
obdfs_from_inode(oa, inode);
err = obd_brw(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo,
- &page, &count, &offset, &flags);
+ &page, &count, &offset, &flags);
//if ( !err )
- // obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */
+ // obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */
obdo_free(oa);
EXIT;
/* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */
static int obdfs_commit_page(struct page *page, int create, int from, int to)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = page->mapping->host;
obd_count num_obdo = 1;
obd_count bufs_per_obdo = 1;
struct obdo *oa;
EXIT;
return -ENOMEM;
}
- oa->o_valid = OBD_MD_FLNOTOBD;
+ oa->o_valid = OBD_MD_FLNOTOBD;
obdfs_from_inode(oa, inode);
- CDEBUG(D_INODE, "commit_page writing (at %d) to %d, count %Ld\n",
- from, to, count);
+ CDEBUG(D_INODE, "commit_page writing (at %d) to %d, count %Ld\n",
+ from, to, count);
err = obd_brw(WRITE, IID(inode), num_obdo, &oa, &bufs_per_obdo,
&page, &count, &offset, &flags);
if ( !err ) {
SetPageUptodate(page);
- set_page_clean(page);
- }
+ set_page_clean(page);
+ }
//if ( !err )
- // obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */
+ // obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */
obdo_free(oa);
EXIT;
/* returns the page unlocked, but with a reference */
int obdfs_writepage(struct page *page)
{
- int rc;
- struct inode *inode = page->mapping->host;
+ int rc;
+ struct inode *inode = page->mapping->host;
ENTRY;
- CERROR("---> writepage called ino %ld!\n", inode->i_ino);
- BUG();
- rc = obdfs_brw(OBD_BRW_WRITE, inode, page, 1);
- if ( !rc ) {
- set_page_clean(page);
- } else {
- CDEBUG(D_INODE, "--> GRR %d\n", rc);
- }
+ CERROR("---> writepage called ino %ld!\n", inode->i_ino);
+ LBUG();
+ rc = obdfs_brw(OBD_BRW_WRITE, inode, page, 1);
+ if ( !rc ) {
+ set_page_clean(page);
+ } else {
+ CDEBUG(D_INODE, "--> GRR %d\n", rc);
+ }
EXIT;
- return rc;
+ return rc;
}
void write_inode_pages(struct inode *inode)
{
- struct list_head *tmp = &inode->i_mapping->dirty_pages;
-
- while ( (tmp = tmp->next) != &inode->i_mapping->dirty_pages) {
- struct page *page;
- page = list_entry(tmp, struct page, list);
- obdfs_writepage(page);
- }
+ struct list_head *tmp = &inode->i_mapping->dirty_pages;
+
+ while ( (tmp = tmp->next) != &inode->i_mapping->dirty_pages) {
+ struct page *page;
+ page = list_entry(tmp, struct page, list);
+ obdfs_writepage(page);
+ }
}
/* returns the page unlocked, but with a reference */
int obdfs_readpage(struct file *file, struct page *page)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = page->mapping->host;
int rc;
ENTRY;
- if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT)
- <= page->index) {
- memset(kmap(page), 0, PAGE_CACHE_SIZE);
- kunmap(page);
- goto readpage_out;
- }
+ if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT)
+ <= page->index) {
+ memset(kmap(page), 0, PAGE_CACHE_SIZE);
+ kunmap(page);
+ goto readpage_out;
+ }
- if (Page_Uptodate(page)) {
- EXIT;
- goto readpage_out;
- }
+ if (Page_Uptodate(page)) {
+ EXIT;
+ goto readpage_out;
+ }
rc = obdfs_brw(READ, inode, page, 0);
if ( rc ) {
- EXIT;
- return rc;
+ EXIT;
+ return rc;
}
readpage_out:
- SetPageUptodate(page);
- UnlockPage(page);
+ SetPageUptodate(page);
+ UnlockPage(page);
EXIT;
return 0;
} /* obdfs_readpage */
int rc = 0;
ENTRY;
- kmap(page);
+ kmap(page);
if (Page_Uptodate(page)) {
EXIT;
- goto prepare_done;
+ goto prepare_done;
}
if ( (from <= offset) && (to >= offset + PAGE_SIZE) ) {
}
prepare_done:
- set_page_dirty(page);
- //SetPageDirty(page);
+ set_page_dirty(page);
+ //SetPageDirty(page);
EXIT;
return rc;
}
}
err = obd_brw(OBD_BRW_WRITE, IID(inodes[0]), num_obdos, obdos,
- oa_bufs, pages, counts, offsets, flags);
+ oa_bufs, pages, counts, offsets, flags);
CDEBUG(D_INFO, "BRW done\n");
/* release the pages from the page cache */
--num_obdos;
CDEBUG(D_INFO, "free obdo %ld\n",(long)obdos[num_obdos]->o_id);
/* copy o_blocks to i_blocks */
- obdfs_set_size (inodes[num_obdos], obdos[num_obdos]->o_size);
+ obdfs_set_size (inodes[num_obdos], obdos[num_obdos]->o_size);
//obdfs_to_inode(inodes[num_obdos], obdos[num_obdos]);
obdo_free(obdos[num_obdos]);
}
obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
list_add(&pgrq->rq_plist, obdfs_iplist(inode));
obdfs_cache_count++;
- //CERROR("-- count %d\n", obdfs_cache_count);
+ //CERROR("-- count %d\n", obdfs_cache_count);
/* If inode isn't already on superblock inodes list, add it.
*
void rebalance(void)
{
- if (obdfs_cache_count > 60000) {
- CERROR("-- count %ld\n", obdfs_cache_count);
- //obdfs_flush_dirty_pages(~0UL);
- CERROR("-- count %ld\n", obdfs_cache_count);
- }
+ if (obdfs_cache_count > 60000) {
+ CERROR("-- count %ld\n", obdfs_cache_count);
+ //obdfs_flush_dirty_pages(~0UL);
+ CERROR("-- count %ld\n", obdfs_cache_count);
+ }
}
if ( !err ) {
SetPageUptodate(page);
- set_page_clean(page);
- }
+ set_page_clean(page);
+ }
EXIT;
return err;
} /* obdfs_do_writepage */
int obdfs_commit_write(struct file *file, struct page *page, unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
- int rc = 0;
+ int rc = 0;
loff_t len = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
- ENTRY;
- CDEBUG(D_INODE, "commit write ino %ld (end at %Ld) from %d to %d ,ind %ld\n",
- inode->i_ino, len, from, to, page->index);
+ ENTRY;
+ CDEBUG(D_INODE, "commit write ino %ld (end at %Ld) from %d to %d ,ind %ld\n",
+ inode->i_ino, len, from, to, page->index);
- if (cache_writes == 0) {
- rc = obdfs_commit_page(page, 1, from, to);
- }
+ if (cache_writes == 0) {
+ rc = obdfs_commit_page(page, 1, from, to);
+ }
if (len > inode->i_size) {
- obdfs_set_size(inode, len);
+ obdfs_set_size(inode, len);
}
kunmap(page);
- EXIT;
+ EXIT;
return rc;
}
//obdfs_dequeue_pages(inode);
oa = obdo_alloc();
if ( !oa ) {
- err = -ENOMEM;
+ err = -ENOMEM;
CERROR("obdo_alloc failed!\n");
} else {
oa->o_valid = OBD_MD_FLNOTOBD;
struct ptlrpc_client *osc_con2cl(struct obd_conn *conn)
{
- struct osc_obd *osc = &conn->oc_dev->u.osc;
- return osc->osc_peer;
+ struct osc_obd *osc = &conn->oc_dev->u.osc;
+ return osc->osc_peer;
}
static int osc_connect(struct obd_conn *conn)
{
- struct ptlrpc_request *request;
- struct ptlrpc_client *peer = osc_con2cl(conn);
- int rc;
- ENTRY;
-
- request = ptlrpc_prep_req(peer, OST_CONNECT, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
-
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
-
- rc = ptlrpc_queue_wait(peer, request);
- if (rc) {
- EXIT;
- goto out;
- }
+ struct ptlrpc_request *request;
+ struct ptlrpc_client *peer = osc_con2cl(conn);
+ int rc;
+ ENTRY;
+
+ request = ptlrpc_prep_req(peer, OST_CONNECT, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
+
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
+
+ rc = ptlrpc_queue_wait(peer, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
- CDEBUG(D_INODE, "received connid %d\n", request->rq_rep.ost->connid);
+ CDEBUG(D_INODE, "received connid %d\n", request->rq_rep.ost->connid);
- conn->oc_id = request->rq_rep.ost->connid;
+ conn->oc_id = request->rq_rep.ost->connid;
out:
- ptlrpc_free_req(request);
- EXIT;
- return rc;
+ ptlrpc_free_req(request);
+ EXIT;
+ return rc;
}
static int osc_disconnect(struct obd_conn *conn)
{
- struct ptlrpc_request *request;
- struct ptlrpc_client *peer = osc_con2cl(conn);
- int rc;
- ENTRY;
-
- request = ptlrpc_prep_req(peer, OST_DISCONNECT, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
- request->rq_req.ost->connid = conn->oc_id;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
-
- rc = ptlrpc_queue_wait(peer, request);
- if (rc) {
- EXIT;
- goto out;
- }
+ struct ptlrpc_request *request;
+ struct ptlrpc_client *peer = osc_con2cl(conn);
+ int rc;
+ ENTRY;
+
+ request = ptlrpc_prep_req(peer, OST_DISCONNECT, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
+ request->rq_req.ost->connid = conn->oc_id;
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
+
+ rc = ptlrpc_queue_wait(peer, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
out:
- ptlrpc_free_req(request);
- EXIT;
- return rc;
+ ptlrpc_free_req(request);
+ EXIT;
+ return rc;
}
static int osc_getattr(struct obd_conn *conn, struct obdo *oa)
{
- struct ptlrpc_request *request;
- struct ptlrpc_client *peer = osc_con2cl(conn);
- int rc;
-
- request = ptlrpc_prep_req(peer, OST_GETATTR, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
-
- memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
+ struct ptlrpc_request *request;
+ struct ptlrpc_client *peer = osc_con2cl(conn);
+ int rc;
+
+ request = ptlrpc_prep_req(peer, OST_GETATTR, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
+
+ memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
request->rq_req.ost->connid = conn->oc_id;
- request->rq_req.ost->oa.o_valid = ~0;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
-
- rc = ptlrpc_queue_wait(peer, request);
- if (rc) {
- EXIT;
- goto out;
- }
-
- CDEBUG(D_INODE, "mode: %o\n", request->rq_rep.ost->oa.o_mode);
- if (oa) {
- memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
- }
+ request->rq_req.ost->oa.o_valid = ~0;
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
+
+ rc = ptlrpc_queue_wait(peer, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
+
+ CDEBUG(D_INODE, "mode: %o\n", request->rq_rep.ost->oa.o_mode);
+ if (oa) {
+ memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
+ }
out:
- ptlrpc_free_req(request);
- return 0;
+ ptlrpc_free_req(request);
+ return 0;
}
static int osc_open(struct obd_conn *conn, struct obdo *oa)
{
- struct ptlrpc_request *request;
- struct ptlrpc_client *peer = osc_con2cl(conn);
- int rc;
-
- request = ptlrpc_prep_req(peer, OST_OPEN, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
-
- memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
+ struct ptlrpc_request *request;
+ struct ptlrpc_client *peer = osc_con2cl(conn);
+ int rc;
+
+ request = ptlrpc_prep_req(peer, OST_OPEN, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
+
+ memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
request->rq_req.ost->connid = conn->oc_id;
if (request->rq_req.ost->oa.o_valid != (OBD_MD_FLMODE | OBD_MD_FLID))
- BUG();
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
-
- rc = ptlrpc_queue_wait(peer, request);
- if (rc) {
- EXIT;
- goto out;
- }
-
- CDEBUG(D_INODE, "mode: %o\n", request->rq_rep.ost->oa.o_mode);
- if (oa) {
- memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
- }
+ LBUG();
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
+
+ rc = ptlrpc_queue_wait(peer, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
+
+ CDEBUG(D_INODE, "mode: %o\n", request->rq_rep.ost->oa.o_mode);
+ if (oa) {
+ memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
+ }
out:
- ptlrpc_free_req(request);
- return 0;
+ ptlrpc_free_req(request);
+ return 0;
}
static int osc_close(struct obd_conn *conn, struct obdo *oa)
{
- struct ptlrpc_request *request;
- struct ptlrpc_client *peer = osc_con2cl(conn);
- int rc;
-
- request = ptlrpc_prep_req(peer, OST_CLOSE, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
-
- memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
+ struct ptlrpc_request *request;
+ struct ptlrpc_client *peer = osc_con2cl(conn);
+ int rc;
+
+ request = ptlrpc_prep_req(peer, OST_CLOSE, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
+
+ memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
request->rq_req.ost->connid = conn->oc_id;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
-
- rc = ptlrpc_queue_wait(peer, request);
- if (rc) {
- EXIT;
- goto out;
- }
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
+
+ rc = ptlrpc_queue_wait(peer, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
- CDEBUG(D_INODE, "mode: %o\n", request->rq_rep.ost->oa.o_mode);
- if (oa) {
- memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
- }
+ CDEBUG(D_INODE, "mode: %o\n", request->rq_rep.ost->oa.o_mode);
+ if (oa) {
+ memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
+ }
out:
- ptlrpc_free_req(request);
- return 0;
+ ptlrpc_free_req(request);
+ return 0;
}
static int osc_setattr(struct obd_conn *conn, struct obdo *oa)
{
- struct ptlrpc_request *request;
- struct ptlrpc_client *peer = osc_con2cl(conn);
- int rc;
-
- request = ptlrpc_prep_req(peer, OST_SETATTR, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
-
- memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
+ struct ptlrpc_request *request;
+ struct ptlrpc_client *peer = osc_con2cl(conn);
+ int rc;
+
+ request = ptlrpc_prep_req(peer, OST_SETATTR, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
+
+ memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
request->rq_req.ost->connid = conn->oc_id;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
-
- rc = ptlrpc_queue_wait(peer, request);
- if (rc) {
- EXIT;
- goto out;
- }
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
+
+ rc = ptlrpc_queue_wait(peer, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
out:
- ptlrpc_free_req(request);
- return 0;
+ ptlrpc_free_req(request);
+ return 0;
}
static int osc_create(struct obd_conn *conn, struct obdo *oa)
{
- struct ptlrpc_request *request;
- struct ptlrpc_client *peer = osc_con2cl(conn);
- int rc;
-
- if (!oa) {
- CERROR("oa NULL\n");
- }
- request = ptlrpc_prep_req(peer, OST_CREATE, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
-
- memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
+ struct ptlrpc_request *request;
+ struct ptlrpc_client *peer = osc_con2cl(conn);
+ int rc;
+
+ if (!oa) {
+ CERROR("oa NULL\n");
+ }
+ request = ptlrpc_prep_req(peer, OST_CREATE, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
+
+ memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
request->rq_req.ost->connid = conn->oc_id;
- request->rq_req.ost->oa.o_valid = ~0;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
-
- rc = ptlrpc_queue_wait(peer, request);
- if (rc) {
- EXIT;
- goto out;
- }
- memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
+ request->rq_req.ost->oa.o_valid = ~0;
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
+
+ rc = ptlrpc_queue_wait(peer, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
+ memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
out:
- ptlrpc_free_req(request);
- return 0;
+ ptlrpc_free_req(request);
+ return 0;
}
static int osc_punch(struct obd_conn *conn, struct obdo *oa, obd_size count,
obd_off offset)
{
- struct ptlrpc_request *request;
- struct ptlrpc_client *peer = osc_con2cl(conn);
- int rc;
-
- if (!oa) {
- CERROR("oa NULL\n");
- }
- request = ptlrpc_prep_req(peer, OST_PUNCH, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
-
- memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
+ struct ptlrpc_request *request;
+ struct ptlrpc_client *peer = osc_con2cl(conn);
+ int rc;
+
+ if (!oa) {
+ CERROR("oa NULL\n");
+ }
+ request = ptlrpc_prep_req(peer, OST_PUNCH, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
+
+ memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
request->rq_req.ost->connid = conn->oc_id;
- request->rq_req.ost->oa.o_valid = ~0;
- request->rq_req.ost->oa.o_size = offset;
- request->rq_req.ost->oa.o_blocks = count;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
-
- rc = ptlrpc_queue_wait(peer, request);
- if (rc) {
- EXIT;
- goto out;
- }
- memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
+ request->rq_req.ost->oa.o_valid = ~0;
+ request->rq_req.ost->oa.o_size = offset;
+ request->rq_req.ost->oa.o_blocks = count;
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
+
+ rc = ptlrpc_queue_wait(peer, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
+ memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
out:
- ptlrpc_free_req(request);
- return 0;
+ ptlrpc_free_req(request);
+ return 0;
}
static int osc_destroy(struct obd_conn *conn, struct obdo *oa)
{
- struct ptlrpc_request *request;
- struct ptlrpc_client *peer = osc_con2cl(conn);
- int rc;
-
- if (!oa) {
- CERROR("oa NULL\n");
- }
- request = ptlrpc_prep_req(peer, OST_DESTROY, 0, NULL, 0, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
-
- memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
+ struct ptlrpc_request *request;
+ struct ptlrpc_client *peer = osc_con2cl(conn);
+ int rc;
+
+ if (!oa) {
+ CERROR("oa NULL\n");
+ }
+ request = ptlrpc_prep_req(peer, OST_DESTROY, 0, NULL, 0, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
+
+ memcpy(&request->rq_req.ost->oa, oa, sizeof(*oa));
request->rq_req.ost->connid = conn->oc_id;
- request->rq_req.ost->oa.o_valid = ~0;
- request->rq_replen =
- sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
-
- rc = ptlrpc_queue_wait(peer, request);
- if (rc) {
- EXIT;
- goto out;
- }
- memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
+ request->rq_req.ost->oa.o_valid = ~0;
+ request->rq_replen =
+ sizeof(struct ptlrep_hdr) + sizeof(struct ost_rep);
+
+ rc = ptlrpc_queue_wait(peer, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
+ memcpy(oa, &request->rq_rep.ost->oa, sizeof(*oa));
out:
- ptlrpc_free_req(request);
- return 0;
+ ptlrpc_free_req(request);
+ return 0;
}
int osc_sendpage(struct obd_conn *conn, struct ptlrpc_request *req,
bulk->b_buf = (void *)(unsigned long)src->addr;
bulk->b_buflen = src->len;
bulk->b_xid = dst->xid;
- rc = ptlrpc_send_bulk(bulk, OSC_BULK_PORTAL);
+ rc = ptlrpc_send_bulk(bulk, OSC_BULK_PORTAL);
if (rc != 0) {
CERROR("send_bulk failed: %d\n", rc);
- BUG();
+ LBUG();
return rc;
}
wait_event_interruptible(bulk->b_waitq,
obd_count *oa_bufs, struct page **buf, obd_size *count,
obd_off *offset, obd_flag *flags)
{
- struct ptlrpc_client *cl = osc_con2cl(conn);
+ struct ptlrpc_client *cl = osc_con2cl(conn);
struct ptlrpc_request *request;
int pages;
- int rc;
- struct obd_ioobj ioo;
- struct niobuf src;
- int size1, size2 = 0;
- void *ptr1, *ptr2;
- int i, j, n;
+ int rc;
+ struct obd_ioobj ioo;
+ struct niobuf src;
+ int size1, size2 = 0;
+ void *ptr1, *ptr2;
+ int i, j, n;
struct ptlrpc_bulk_desc **bulk;
- size1 = num_oa * sizeof(ioo);
+ size1 = num_oa * sizeof(ioo);
pages = 0;
for (i = 0; i < num_oa; i++)
pages += oa_bufs[i];
size2 = pages * sizeof(src);
- request = ptlrpc_prep_req(cl, OST_BRW, size1, NULL, size2, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
+ request = ptlrpc_prep_req(cl, OST_BRW, size1, NULL, size2, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
request->rq_req.ost->cmd = OBD_BRW_READ;
OBD_ALLOC(bulk, pages * sizeof(struct ptlrpc_bulk_desc *));
obd_count *oa_bufs, struct page **buf, obd_size *count,
obd_off *offset, obd_flag *flags)
{
- struct ptlrpc_client *cl = osc_con2cl(conn);
+ struct ptlrpc_client *cl = osc_con2cl(conn);
struct ptlrpc_request *request;
- struct obd_ioobj ioo;
- struct niobuf *src;
- int pages, rc, i, j, n, size1, size2 = 0;
- void *ptr1, *ptr2;
+ struct obd_ioobj ioo;
+ struct niobuf *src;
+ int pages, rc, i, j, n, size1, size2 = 0;
+ void *ptr1, *ptr2;
- size1 = num_oa * sizeof(ioo);
+ size1 = num_oa * sizeof(ioo);
pages = 0;
for (i = 0; i < num_oa; i++)
pages += oa_bufs[i];
}
memset((char *)src, 0, size2);
- request = ptlrpc_prep_req(cl, OST_BRW, size1, NULL, size2, NULL);
- if (!request) {
- CERROR("cannot pack req!\n");
- return -ENOMEM;
- }
+ request = ptlrpc_prep_req(cl, OST_BRW, size1, NULL, size2, NULL);
+ if (!request) {
+ CERROR("cannot pack req!\n");
+ return -ENOMEM;
+ }
request->rq_req.ost->cmd = OBD_BRW_WRITE;
- n = 0;
- ptr1 = ost_req_buf1(request->rq_req.ost);
- ptr2 = ost_req_buf2(request->rq_req.ost);
+ n = 0;
+ ptr1 = ost_req_buf1(request->rq_req.ost);
+ ptr2 = ost_req_buf2(request->rq_req.ost);
for (i = 0; i < num_oa; i++) {
- ost_pack_ioo(&ptr1, oa[i], oa_bufs[i]);
+ ost_pack_ioo(&ptr1, oa[i], oa_bufs[i]);
for (j = 0; j < oa_bufs[i]; j++) {
ost_pack_niobuf(&ptr2, kmap(buf[n]), offset[n],
count[n], flags[n], 0);
- n++;
- }
- }
+ n++;
+ }
+ }
memcpy((char *)src, (char *)ost_req_buf2(request->rq_req.ost), size2);
- request->rq_replen = sizeof(struct ptlrep_hdr) +
+ request->rq_replen = sizeof(struct ptlrep_hdr) +
sizeof(struct ost_rep) + pages * sizeof(struct niobuf);
- rc = ptlrpc_queue_wait(cl, request);
- if (rc) {
- EXIT;
- goto out;
- }
+ rc = ptlrpc_queue_wait(cl, request);
+ if (rc) {
+ EXIT;
+ goto out;
+ }
ptr2 = ost_rep_buf2(request->rq_rep.ost);
if (request->rq_rep.ost->buflen2 != n * sizeof(struct niobuf)) {
n = 0;
for (i = 0; i < num_oa; i++) {
for (j = 0; j < oa_bufs[i]; j++) {
- struct niobuf *dst;
- ost_unpack_niobuf(&ptr2, &dst);
- osc_sendpage(conn, request, dst, &src[n]);
- n++;
- }
- }
+ struct niobuf *dst;
+ ost_unpack_niobuf(&ptr2, &dst);
+ osc_sendpage(conn, request, dst, &src[n]);
+ n++;
+ }
+ }
OBD_FREE(src, size2);
out:
- n = 0;
+ n = 0;
for (i = 0; i < num_oa; i++) {
for (j = 0; j < oa_bufs[i]; j++) {
- kunmap(buf[n]);
- n++;
- }
- }
+ kunmap(buf[n]);
+ n++;
+ }
+ }
- ptlrpc_free_req(request);
- return 0;
+ ptlrpc_free_req(request);
+ return 0;
}
int osc_brw(int rw, struct obd_conn *conn, obd_count num_oa,
- struct obdo **oa, obd_count *oa_bufs, struct page **buf,
- obd_size *count, obd_off *offset, obd_flag *flags)
+ struct obdo **oa, obd_count *oa_bufs, struct page **buf,
+ obd_size *count, obd_off *offset, obd_flag *flags)
{
if (rw == OBD_BRW_READ) {
return osc_brw_read(conn, num_oa, oa, oa_bufs, buf, count,
/* mount the file system (secretly) */
static int osc_setup(struct obd_device *obddev, obd_count len,
- void *buf)
-
+ void *buf)
+
{
- struct osc_obd *osc = &obddev->u.osc;
- struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
- int rc;
- int dev = data->ioc_dev;
+ struct osc_obd *osc = &obddev->u.osc;
+ struct obd_ioctl_data *data = (struct obd_ioctl_data *)buf;
+ int rc;
+ int dev = data->ioc_dev;
ENTRY;
OBD_ALLOC(osc->osc_peer, sizeof(*osc->osc_peer));
static int osc_cleanup(struct obd_device * obddev)
{
- struct osc_obd *osc = &obddev->u.osc;
+ struct osc_obd *osc = &obddev->u.osc;
if (osc->osc_peer != NULL)
OBD_FREE(osc->osc_peer, sizeof(*osc->osc_peer));
}
struct obd_ops osc_obd_ops = {
- o_setup: osc_setup,
- o_cleanup: osc_cleanup,
- o_create: osc_create,
- o_destroy: osc_destroy,
- o_getattr: osc_getattr,
- o_setattr: osc_setattr,
- o_open: osc_open,
- o_close: osc_close,
- o_connect: osc_connect,
- o_disconnect: osc_disconnect,
- o_brw: osc_brw,
- o_punch: osc_punch
+ o_setup: osc_setup,
+ o_cleanup: osc_cleanup,
+ o_create: osc_create,
+ o_destroy: osc_destroy,
+ o_getattr: osc_getattr,
+ o_setattr: osc_setattr,
+ o_open: osc_open,
+ o_close: osc_close,
+ o_connect: osc_connect,
+ o_disconnect: osc_disconnect,
+ o_brw: osc_brw,
+ o_punch: osc_punch
};
static int __init osc_init(void)
{
obd_register_type(&osc_obd_ops, LUSTRE_OSC_NAME);
- return 0;
+ return 0;
}
static void __exit osc_exit(void)
{
- obd_unregister_type(LUSTRE_OSC_NAME);
+ obd_unregister_type(LUSTRE_OSC_NAME);
}
MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
for (i = 0; i < objcount; i++) {
ost_unpack_ioo((void *)&tmp1, &ioo);
if (tmp2 + ioo->ioo_bufcnt > end2) {
- BUG();
+ LBUG();
rc = -EFAULT;
break;
}
static int ost_handle(struct obd_device *obddev, struct ptlrpc_service *svc,
struct ptlrpc_request *req)
{
- int rc;
- struct ost_obd *ost = &obddev->u.ost;
- struct ptlreq_hdr *hdr;
-
- ENTRY;
-
- hdr = (struct ptlreq_hdr *)req->rq_reqbuf;
- if (NTOH__u32(hdr->type) != OST_TYPE_REQ) {
- CERROR("lustre_ost: wrong packet type sent %d\n",
- NTOH__u32(hdr->type));
- BUG();
- rc = -EINVAL;
+ int rc;
+ struct ost_obd *ost = &obddev->u.ost;
+ struct ptlreq_hdr *hdr;
+
+ ENTRY;
+
+ hdr = (struct ptlreq_hdr *)req->rq_reqbuf;
+ if (NTOH__u32(hdr->type) != PTL_RPC_REQUEST) {
+ CERROR("lustre_ost: wrong packet type sent %d\n",
+ NTOH__u32(hdr->type));
+ LBUG();
+ rc = -EINVAL;
GOTO(out, rc);
- }
+ }
rc = ost_unpack_req(req->rq_reqbuf, req->rq_reqlen,
&req->rq_reqhdr, &req->rq_req);
RETURN(-EINVAL);
}
- ost->ost_service = ptlrpc_init_svc( 2 * 1024,
- OST_REQUEST_PORTAL,
- OSC_REPLY_PORTAL,
- "self",
- ost_unpack_req,
- ost_pack_rep,
- ost_handle);
+ ost->ost_service = ptlrpc_init_svc(2 * 1024,
+ OST_REQUEST_PORTAL, OSC_REPLY_PORTAL,
+ "self", ost_handle);
if (!ost->ost_service) {
obd_disconnect(&ost->ost_conn);
RETURN(-EINVAL);
int ptlrpc_enqueue(struct ptlrpc_client *peer, struct ptlrpc_request *req)
{
- struct ptlrpc_request *srv_req;
-
- if (!peer->cli_obd) {
- EXIT;
- return -1;
- }
-
- OBD_ALLOC(srv_req, sizeof(*srv_req));
- if (!srv_req) {
- EXIT;
- return -ENOMEM;
- }
+ struct ptlrpc_request *srv_req;
+
+ if (!peer->cli_obd) {
+ EXIT;
+ return -1;
+ }
+
+ OBD_ALLOC(srv_req, sizeof(*srv_req));
+ if (!srv_req) {
+ EXIT;
+ return -ENOMEM;
+ }
CDEBUG(0, "peer obd minor %d, incoming req %p, srv_req %p\n",
- peer->cli_obd->obd_minor, req, srv_req);
+ peer->cli_obd->obd_minor, req, srv_req);
- memset(srv_req, 0, sizeof(*req));
+ memset(srv_req, 0, sizeof(*req));
- /* move the request buffer */
- srv_req->rq_reqbuf = req->rq_reqbuf;
- srv_req->rq_reqlen = req->rq_reqlen;
- srv_req->rq_obd = peer->cli_obd;
+ /* move the request buffer */
+ srv_req->rq_reqbuf = req->rq_reqbuf;
+ srv_req->rq_reqlen = req->rq_reqlen;
+ srv_req->rq_obd = peer->cli_obd;
- /* remember where it came from */
- srv_req->rq_reply_handle = req;
+ /* remember where it came from */
+ srv_req->rq_reply_handle = req;
spin_lock(&peer->cli_lock);
- list_add(&srv_req->rq_list, &peer->cli_obd->obd_req_list);
+ list_add(&srv_req->rq_list, &peer->cli_obd->obd_req_list);
spin_unlock(&peer->cli_lock);
- wake_up(&peer->cli_obd->obd_req_waitq);
- return 0;
+ wake_up(&peer->cli_obd->obd_req_waitq);
+ return 0;
}
int ptlrpc_connect_client(int dev, char *uuid, int req_portal, int rep_portal,
memset(cl, 0, sizeof(*cl));
spin_lock_init(&cl->cli_lock);
- cl->cli_xid = 1;
- cl->cli_obd = NULL;
- cl->cli_request_portal = req_portal;
- cl->cli_reply_portal = rep_portal;
- cl->cli_rep_unpack = rep_unpack;
- cl->cli_req_pack = req_pack;
-
- /* non networked client */
- if (dev >= 0 && dev < MAX_OBD_DEVICES) {
- struct obd_device *obd = &obd_dev[dev];
-
- if ((!obd->obd_flags & OBD_ATTACHED) ||
- (!obd->obd_flags & OBD_SET_UP)) {
- CERROR("target device %d not att or setup\n", dev);
- return -EINVAL;
- }
+ cl->cli_xid = 1;
+ cl->cli_obd = NULL;
+ cl->cli_request_portal = req_portal;
+ cl->cli_reply_portal = rep_portal;
+ cl->cli_rep_unpack = rep_unpack;
+ cl->cli_req_pack = req_pack;
+
+ /* non networked client */
+ if (dev >= 0 && dev < MAX_OBD_DEVICES) {
+ struct obd_device *obd = &obd_dev[dev];
+
+ if ((!obd->obd_flags & OBD_ATTACHED) ||
+ (!obd->obd_flags & OBD_SET_UP)) {
+ CERROR("target device %d not att or setup\n", dev);
+ return -EINVAL;
+ }
if (strcmp(obd->obd_type->typ_name, "ost") &&
strcmp(obd->obd_type->typ_name, "mds")) {
return -EINVAL;
}
- cl->cli_obd = &obd_dev[dev];
- return 0;
- }
+ cl->cli_obd = &obd_dev[dev];
+ return 0;
+ }
- /* networked */
- err = kportal_uuid_to_peer(uuid, &cl->cli_server);
+ /* networked */
+ err = kportal_uuid_to_peer(uuid, &cl->cli_server);
if (err != 0)
CERROR("cannot find peer %s!\n", uuid);
int opcode, int namelen, char *name,
int tgtlen, char *tgt)
{
- struct ptlrpc_request *request;
- int rc;
- ENTRY;
-
- OBD_ALLOC(request, sizeof(*request));
- if (!request) {
- CERROR("request allocation out of memory\n");
- return NULL;
- }
+ struct ptlrpc_request *request;
+ int rc;
+ ENTRY;
+
+ OBD_ALLOC(request, sizeof(*request));
+ if (!request) {
+ CERROR("request allocation out of memory\n");
+ return NULL;
+ }
- memset(request, 0, sizeof(*request));
+ memset(request, 0, sizeof(*request));
//spin_lock_init(&request->rq_lock);
spin_lock(&cl->cli_lock);
- request->rq_xid = cl->cli_xid++;
+ request->rq_xid = cl->cli_xid++;
spin_unlock(&cl->cli_lock);
- rc = cl->cli_req_pack(name, namelen, tgt, tgtlen,
- &request->rq_reqhdr, &request->rq_req,
- &request->rq_reqlen, &request->rq_reqbuf);
- if (rc) {
- CERROR("cannot pack request %d\n", rc);
- return NULL;
- }
- request->rq_reqhdr->opc = opcode;
- request->rq_reqhdr->xid = request->rq_xid;
-
- EXIT;
- return request;
+ rc = cl->cli_req_pack(name, namelen, tgt, tgtlen,
+ &request->rq_reqhdr, &request->rq_req,
+ &request->rq_reqlen, &request->rq_reqbuf);
+ if (rc) {
+ CERROR("cannot pack request %d\n", rc);
+ return NULL;
+ }
+ request->rq_reqhdr->opc = opcode;
+ request->rq_reqhdr->xid = request->rq_xid;
+
+ EXIT;
+ return request;
}
void ptlrpc_free_req(struct ptlrpc_request *request)
if (request->rq_repbuf != NULL)
OBD_FREE(request->rq_repbuf, request->rq_replen);
- OBD_FREE(request, sizeof(*request));
+ OBD_FREE(request, sizeof(*request));
}
static int ptlrpc_check_reply(struct ptlrpc_request *req)
int ptlrpc_queue_wait(struct ptlrpc_client *cl, struct ptlrpc_request *req)
-
{
- int rc = 0;
+ int rc = 0;
ENTRY;
- init_waitqueue_head(&req->rq_wait_for_rep);
-
- if (cl->cli_obd) {
- /* Local delivery */
- ENTRY;
- rc = ptlrpc_enqueue(cl, req);
- } else {
- /* Remote delivery via portals. */
- req->rq_req_portal = cl->cli_request_portal;
- req->rq_reply_portal = cl->cli_reply_portal;
- rc = ptl_send_rpc(req, &cl->cli_server);
- }
- if (rc) {
+ init_waitqueue_head(&req->rq_wait_for_rep);
+
+ if (cl->cli_obd) {
+ /* Local delivery */
+ rc = ptlrpc_enqueue(cl, req);
+ } else {
+ /* Remote delivery via portals. */
+ req->rq_req_portal = cl->cli_request_portal;
+ req->rq_reply_portal = cl->cli_reply_portal;
+ rc = ptl_send_rpc(req, &cl->cli_server);
+ }
+ if (rc) {
CERROR("error %d, opcode %d\n", rc, req->rq_reqhdr->opc);
- return -rc;
- }
+ return -rc;
+ }
CDEBUG(D_OTHER, "-- sleeping\n");
wait_event_interruptible(req->rq_wait_for_rep, ptlrpc_check_reply(req));
CERROR("Unknown reason for wakeup\n");
/* XXX Phil - I end up here when I kill obdctl */
ptlrpc_abort(req);
- //BUG();
+ //LBUG();
EXIT;
rc = -EINTR;
goto out;
}
- rc = cl->cli_rep_unpack(req->rq_repbuf, req->rq_replen,
+ rc = cl->cli_rep_unpack(req->rq_repbuf, req->rq_replen,
&req->rq_rephdr, &req->rq_rep);
- if (rc) {
- CERROR("unpack_rep failed: %d\n", rc);
+ if (rc) {
+ CERROR("unpack_rep failed: %d\n", rc);
goto out;
- }
+ }
CDEBUG(D_NET, "got rep %d\n", req->rq_rephdr->xid);
- if ( req->rq_rephdr->status == 0 )
+ if ( req->rq_rephdr->status == 0 )
CDEBUG(D_NET, "--> buf %p len %d status %d\n", req->rq_repbuf,
req->rq_replen, req->rq_rephdr->status);
- EXIT;
+ EXIT;
out:
//spin_unlock(&req->rq_lock);
- return rc;
+ return rc;
}
*/
static int sent_packet_callback(ptl_event_t *ev, void *data)
{
+ ptl_event_t junk_ev;
+
ENTRY;
+ PtlEQGet(sent_pkt_eq, &junk_ev);
+
if (ev->type == PTL_EVENT_SENT) {
OBD_FREE(ev->mem_desc.start, ev->mem_desc.length);
} else {
// XXX make sure we understand all events, including ACK's
CERROR("Unknown event %d\n", ev->type);
- BUG();
+ LBUG();
}
EXIT;
} else {
// XXX make sure we understand all events, including ACK's
CERROR("Unknown event %d\n", ev->type);
- BUG();
+ LBUG();
}
EXIT;
spin_lock(&service->srv_lock);
if ( ev->mem_desc.start !=
service->srv_md[service->srv_md_active].start ) {
- BUG();
+ LBUG();
}
service->srv_ref_count[service->srv_md_active]++;
if (rc != PTL_OK) {
CERROR("PtlMEUnlink failed - DROPPING soon: %d\n", rc);
- BUG();
+ LBUG();
spin_unlock(&service->srv_lock);
return rc;
}
if (service->srv_me_h[service->srv_md_active] == 0) {
CERROR("All %d ring ME's are unlinked!\n",
service->srv_ring_length);
- BUG();
+ LBUG();
}
}
wake_up_interruptible(&bulk->b_waitq);
} else {
CERROR("Unexpected event type!\n");
- BUG();
+ LBUG();
}
EXIT;
wake_up_interruptible(&bulk->b_waitq);
} else {
CERROR("Unexpected event type!\n");
- BUG();
+ LBUG();
}
/* FIXME: This should happen unconditionally */
ack = PTL_NOACK_REQ;
break;
default:
- BUG();
+ LBUG();
return -1; /* notreached */
}
request->rq_req_md.options = PTL_MD_OP_PUT;
//CERROR("MDBind (outgoing req/rep/bulk): %Lu\n", (__u64)md_h);
if (rc != 0) {
CERROR("PtlMDBind failed: %d\n", rc);
- BUG();
+ LBUG();
return rc;
}
rc = PtlMDBind(bulk->b_peer.peer_ni, bulk->b_md, &md_h);
if (rc != 0) {
CERROR("PtlMDBind failed: %d\n", rc);
- BUG();
+ LBUG();
return rc;
}
CERROR("PtlPut(%d, %d, %d) failed: %d\n", remote_id.nid,
portal, bulk->b_xid, rc);
PtlMDUnlink(md_h);
- BUG();
+ LBUG();
}
return rc;
bulk->b_xid, 0, PTL_UNLINK, &bulk->b_me_h);
if (rc != PTL_OK) {
CERROR("PtlMEAttach failed: %d\n", rc);
- BUG();
+ LBUG();
EXIT;
goto cleanup1;
}
//CERROR("MDAttach (bulk sink): %Lu\n", (__u64)bulk->b_md_h);
if (rc != PTL_OK) {
CERROR("PtlMDAttach failed: %d\n", rc);
- BUG();
+ LBUG();
EXIT;
goto cleanup2;
}
int ptlrpc_reply(struct obd_device *obddev, struct ptlrpc_service *svc,
struct ptlrpc_request *req)
{
- struct ptlrpc_request *clnt_req = req->rq_reply_handle;
- ENTRY;
+ struct ptlrpc_request *clnt_req = req->rq_reply_handle;
+ ENTRY;
- if (req->rq_reply_handle == NULL) {
- /* This is a request that came from the network via portals. */
+ if (req->rq_reply_handle == NULL) {
+ /* This is a request that came from the network via portals. */
- /* FIXME: we need to increment the count of handled events */
+ /* FIXME: we need to increment the count of handled events */
req->rq_type = PTL_RPC_REPLY;
req->rq_reqhdr->xid = req->rq_reqhdr->xid;
- ptl_send_buf(req, &req->rq_peer, svc->srv_rep_portal);
- } else {
- /* This is a local request that came from another thread. */
-
- /* move the reply to the client */
- clnt_req->rq_replen = req->rq_replen;
- clnt_req->rq_repbuf = req->rq_repbuf;
- req->rq_repbuf = NULL;
- req->rq_replen = 0;
-
- /* free the request buffer */
- OBD_FREE(req->rq_reqbuf, req->rq_reqlen);
- req->rq_reqbuf = NULL;
-
- /* wake up the client */
- wake_up_interruptible(&clnt_req->rq_wait_for_rep);
- }
-
- EXIT;
- return 0;
+ ptl_send_buf(req, &req->rq_peer, svc->srv_rep_portal);
+ } else {
+ /* This is a local request that came from another thread. */
+
+ /* move the reply to the client */
+ clnt_req->rq_replen = req->rq_replen;
+ clnt_req->rq_repbuf = req->rq_repbuf;
+ req->rq_repbuf = NULL;
+ req->rq_replen = 0;
+
+ /* free the request buffer */
+ OBD_FREE(req->rq_reqbuf, req->rq_reqlen);
+ req->rq_reqbuf = NULL;
+
+ /* wake up the client */
+ wake_up_interruptible(&clnt_req->rq_wait_for_rep);
+ }
+
+ EXIT;
+ return 0;
}
int ptlrpc_error(struct obd_device *obddev, struct ptlrpc_service *svc,
struct ptlrpc_request *req)
{
- struct ptlrep_hdr *hdr;
+ struct ptlrep_hdr *hdr;
- ENTRY;
+ ENTRY;
- OBD_ALLOC(hdr, sizeof(*hdr));
- if (!hdr) {
- EXIT;
- return -ENOMEM;
- }
+ OBD_ALLOC(hdr, sizeof(*hdr));
+ if (!hdr) {
+ EXIT;
+ return -ENOMEM;
+ }
- memset(hdr, 0, sizeof(*hdr));
+ memset(hdr, 0, sizeof(*hdr));
- hdr->xid = req->rq_reqhdr->xid;
- hdr->status = req->rq_status;
- hdr->type = OST_TYPE_ERR;
+ hdr->xid = req->rq_reqhdr->xid;
+ hdr->status = req->rq_status;
+ hdr->type = PTL_RPC_ERR;
if (req->rq_repbuf) {
CERROR("req has repbuf\n");
- BUG();
+ LBUG();
}
- req->rq_repbuf = (char *)hdr;
- req->rq_replen = sizeof(*hdr);
+ req->rq_repbuf = (char *)hdr;
+ req->rq_replen = sizeof(*hdr);
- EXIT;
- return ptlrpc_reply(obddev, svc, req);
+ EXIT;
+ return ptlrpc_reply(obddev, svc, req);
}
int ptl_send_rpc(struct ptlrpc_request *request, struct lustre_peer *peer)
{
ptl_process_id_t local_id;
- struct ptlreq_hdr *hdr;
+ struct ptlreq_hdr *hdr;
int rc;
char *repbuf;
ENTRY;
hdr = (struct ptlreq_hdr *)request->rq_reqbuf;
- if (NTOH__u32(hdr->type) != OST_TYPE_REQ) {
- CERROR("lustre_ost: wrong packet type sent %d\n",
- NTOH__u32(hdr->type));
- BUG();
+ if (NTOH__u32(hdr->type) != PTL_RPC_REQUEST) {
+ CERROR("wrong packet type sent %d\n", NTOH__u32(hdr->type));
+ LBUG();
}
if (request->rq_replen == 0) {
CERROR("request->rq_replen is 0!\n");
&request->rq_reply_me_h);
if (rc != PTL_OK) {
CERROR("PtlMEAttach failed: %d\n", rc);
- BUG();
+ LBUG();
EXIT;
goto cleanup;
}
//CERROR("MDAttach (send RPC): %Lu\n", (__u64)request->rq_reply_md_h);
if (rc != PTL_OK) {
CERROR("PtlMDAttach failed: %d\n", rc);
- BUG();
+ LBUG();
EXIT;
goto cleanup2;
}
index++;
}
if (index == service->srv_ring_length)
- BUG();
+ LBUG();
CDEBUG(D_INFO, "MD index=%d Ref Count=%d\n", index,
service->srv_ref_count[index]);
service->srv_ref_count[index]--;
if (service->srv_ref_count[index] < 0)
- BUG();
+ LBUG();
if (service->srv_ref_count[index] == 0 &&
service->srv_me_h[index] == 0) {
PTL_INS_AFTER, &(service->srv_me_h[index]));
if (rc != PTL_OK) {
CERROR("PtlMEInsert failed: %d\n", rc);
- BUG();
+ LBUG();
spin_unlock(&service->srv_lock);
return rc;
}
if (rc != PTL_OK) {
/* XXX cleanup */
CERROR("PtlMDAttach failed: %d\n", rc);
- BUG();
+ LBUG();
spin_unlock(&service->srv_lock);
return rc;
}
}
if (svc->srv_flags & SVC_EVENT)
- BUG();
+ LBUG();
if ( svc->srv_eq_h ) {
int err;
if (err != PTL_EQ_EMPTY) {
CDEBUG(D_NET, "BUG: PtlEQGet returned %d\n", rc);
- BUG();
+ LBUG();
}
EXIT;
struct ptlrpc_service *
ptlrpc_init_svc(__u32 bufsize, int req_portal, int rep_portal, char *uuid,
- req_unpack_t unpack, rep_pack_t pack, svc_handler_t handler)
+ svc_handler_t handler)
{
int err;
struct ptlrpc_service *svc;
svc->srv_buf_size = bufsize;
svc->srv_rep_portal = rep_portal;
svc->srv_req_portal = req_portal;
- svc->srv_req_unpack = unpack;
- svc->srv_rep_pack = pack;
+
svc->srv_handler = handler;
err = kportal_uuid_to_peer(uuid, &svc->srv_self);
if (err) {
SRCDIR="`dirname $0`"
. $SRCDIR/common.sh
-setup
+NETWORK=tcp
+LOCALHOST=localhost
+SERVER=localhost
+PORT=1234
-$PTLCTL <<EOF
-mynid localhost
-setup tcp
-connect localhost 1234
-add_uuid self
-add_uuid ost
-quit
-EOF
-
-echo 0xffffffff > /proc/sys/portals/debug
+setup
+setup_portals
$OBDCTL <<EOF
device 0
setup
setup_portals
-new_fs ext2 /tmp/ost 10000
+new_fs ext2 /tmp/ost 250000
OST=$LOOPDEV
MDSFS=ext2
new_fs ${MDSFS} /tmp/mds 10000
quit
EOF
-mount -t lustre_light -o device=3 none /mnt/obd
+#mount -t lustre_light -o device=3 none /mnt/obd
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2001 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.sf.net/projects/lustre/
+ *
+ * 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.
+ *
+ * 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 Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/param.h>
#include <assert.h>
-#define READLINE_LIBRARY
+#define READLINE_LIBRARY
#include <readline/readline.h>
//extern char **completion_matches __P((char *, rl_compentry_func_t *));
#define CMD_NONE 2
#define CMD_AMBIG 3
-static command_t * top_level; /* Top level of commands, initialized by
- * InitParser */
-static command_t * match_tbl; /* Command completion against this table */
+static command_t * top_level; /* Top level of commands, initialized by
+ * InitParser */
+static command_t * match_tbl; /* Command completion against this table */
static char * parser_prompt = NULL;/* Parser prompt, set by InitParser */
-static int done; /* Set to 1 if user types exit or quit */
+static int done; /* Set to 1 if user types exit or quit */
/* static functions */
static char * skipwhitespace(char * s)
{
- char * t;
- int len;
+ char * t;
+ int len;
- len = (int)strlen(s);
- for (t = s; t <= s + len && isspace(*t); t++);
- return(t);
+ len = (int)strlen(s);
+ for (t = s; t <= s + len && isspace(*t); t++);
+ return(t);
}
static char * skiptowhitespace(char * s)
{
- char * t;
+ char * t;
- for (t = s; *t && !isspace(*t); t++);
- return(t);
+ for (t = s; *t && !isspace(*t); t++);
+ return(t);
}
static int line2args(char *line, char **argv, int maxargs)
{
- char *arg;
- int i = 0;
+ char *arg;
+ int i = 0;
- arg = strtok(line, " \t");
- if ( arg ) {
- argv[i] = arg;
- i++;
- } else
- return 0;
-
- while( (arg = strtok(NULL, " \t")) && (i <= maxargs)) {
- argv[i] = arg;
- i++;
- }
- return i;
+ arg = strtok(line, " \t");
+ if ( arg ) {
+ argv[i] = arg;
+ i++;
+ } else
+ return 0;
+
+ while( (arg = strtok(NULL, " \t")) && (i <= maxargs)) {
+ argv[i] = arg;
+ i++;
+ }
+ return i;
}
/* find a command -- return it if unique otherwise print alternatives */
static command_t *Parser_findargcmd(char *name, command_t cmds[])
{
- command_t *cmd;
- int i;
+ command_t *cmd;
+ int i;
- for (i = 0; cmds[i].pc_name; i++) {
- cmd = &cmds[i];
+ for (i = 0; cmds[i].pc_name; i++) {
+ cmd = &cmds[i];
- if (strlen(name) != strlen(cmd->pc_name))
- continue;
+ if (strlen(name) != strlen(cmd->pc_name))
+ continue;
- if (strlen(name) == strlen(cmd->pc_name)) {
- if (strcmp(name, cmd->pc_name) == 0)
- return cmd;
- else
- continue;
- }
+ if (strlen(name) == strlen(cmd->pc_name)) {
+ if (strcmp(name, cmd->pc_name) == 0)
+ return cmd;
+ else
+ continue;
+ }
- }
- return NULL;
+ }
+ return NULL;
}
int Parser_execarg(int argc, char **argv, command_t cmds[])
{
- command_t *cmd;
- int i;
+ command_t *cmd;
+ int i;
cmd = Parser_findargcmd(argv[0], cmds);
- if ( cmd ) {
- return (cmd->pc_func)(argc, argv);
- } else {
- printf("Try interactive use without arguments or use one of: ");
- for (i=0 ; cmds[i].pc_name ; i++) {
- cmd = &cmds[i];
- printf("\"%s\" ", cmd->pc_name);
- }
- printf("as argument.\n");
- }
- return -1;
+ if ( cmd ) {
+ return (cmd->pc_func)(argc, argv);
+ } else {
+ printf("Try interactive use without arguments or use one of: ");
+ for (i=0 ; cmds[i].pc_name ; i++) {
+ cmd = &cmds[i];
+ printf("\"%s\" ", cmd->pc_name);
+ }
+ printf("as argument.\n");
+ }
+ return -1;
}
/* returns the command_t * (NULL if not found) corresponding to a
point to the following token. Does not modify *name. */
static command_t * find_cmd(char * name, command_t cmds[], char ** next)
{
- int i, len;
+ int i, len;
- if (!cmds || !name )
- return NULL;
+ if (!cmds || !name )
+ return NULL;
- /* This sets name to point to the first non-white space character,
- and next to the first whitespace after name, len to the length: do
- this with strtok*/
- name = skipwhitespace(name);
- *next = skiptowhitespace(name);
- len = *next - name;
- if (len == 0)
- return NULL;
-
- for (i = 0; cmds[i].pc_name; i++) {
- if (strncasecmp(name, cmds[i].pc_name, len) == 0) {
- *next = skipwhitespace(*next);
- return(&cmds[i]);
- }
- }
- return NULL;
+ /* This sets name to point to the first non-white space character,
+ and next to the first whitespace after name, len to the length: do
+ this with strtok*/
+ name = skipwhitespace(name);
+ *next = skiptowhitespace(name);
+ len = *next - name;
+ if (len == 0)
+ return NULL;
+
+ for (i = 0; cmds[i].pc_name; i++) {
+ if (strncasecmp(name, cmds[i].pc_name, len) == 0) {
+ *next = skipwhitespace(*next);
+ return(&cmds[i]);
+ }
+ }
+ return NULL;
}
/* Recursively process a command line string s and find the command
corresponding to it. This can be ambiguous, full, incomplete,
non-existent. */
static int process(char *s, char ** next, command_t *lookup,
- command_t **result, char **prev)
+ command_t **result, char **prev)
{
- *result = find_cmd(s, lookup, next);
- *prev = s;
-
- /* non existent */
- if ( ! *result )
- return CMD_NONE;
-
- /* found entry: is it ambigous, i.e. not exact command name and
- more than one command in the list matches. Note that find_cmd
- points to the first ambiguous entry */
- if ( strncasecmp(s, (*result)->pc_name, strlen((*result)->pc_name)) &&
- find_cmd(s, (*result) + 1, next))
- return CMD_AMBIG;
-
- /* found a unique command: component or full? */
- if ( (*result)->pc_func ) {
- return CMD_COMPLETE;
- } else {
- if ( *next == '\0' ) {
- return CMD_INCOMPLETE;
- } else {
- return process(*next, next, (*result)->pc_sub_cmd, result, prev);
- }
- }
+ *result = find_cmd(s, lookup, next);
+ *prev = s;
+
+ /* non existent */
+ if ( ! *result )
+ return CMD_NONE;
+
+ /* found entry: is it ambigous, i.e. not exact command name and
+ more than one command in the list matches. Note that find_cmd
+ points to the first ambiguous entry */
+ if ( strncasecmp(s, (*result)->pc_name, strlen((*result)->pc_name)) &&
+ find_cmd(s, (*result) + 1, next))
+ return CMD_AMBIG;
+
+ /* found a unique command: component or full? */
+ if ( (*result)->pc_func ) {
+ return CMD_COMPLETE;
+ } else {
+ if ( *next == '\0' ) {
+ return CMD_INCOMPLETE;
+ } else {
+ return process(*next, next, (*result)->pc_sub_cmd, result, prev);
+ }
+ }
}
static char * command_generator(const char * text, int state)
{
- static int index,
- len;
- char *name;
+ static int index,
+ len;
+ char *name;
- /* Do we have a match table? */
- if (!match_tbl)
- return NULL;
+ /* Do we have a match table? */
+ if (!match_tbl)
+ return NULL;
- /* If this is the first time called on this word, state is 0 */
- if (!state) {
- index = 0;
- len = (int)strlen(text);
- }
-
- /* Return the next name in the command list that paritally matches test */
- while ( (name = (match_tbl + index)->pc_name) ) {
- index++;
-
- if (strncasecmp(name, text, len) == 0) {
- return(strdup(name));
- }
- }
-
- /* No more matches */
- return NULL;
+ /* If this is the first time called on this word, state is 0 */
+ if (!state) {
+ index = 0;
+ len = (int)strlen(text);
+ }
+
+ /* Return the next name in the command list that paritally matches test */
+ while ( (name = (match_tbl + index)->pc_name) ) {
+ index++;
+
+ if (strncasecmp(name, text, len) == 0) {
+ return(strdup(name));
+ }
+ }
+
+ /* No more matches */
+ return NULL;
}
/* probably called by readline */
static char **command_completion(char * text, int start, int end)
{
- command_t * table;
- char * pos;
+ command_t * table;
+ char * pos;
- match_tbl = top_level;
- for (table = find_cmd(rl_line_buffer, match_tbl, &pos);
- table;
- table = find_cmd(pos, match_tbl, &pos)) {
+ match_tbl = top_level;
+ for (table = find_cmd(rl_line_buffer, match_tbl, &pos);
+ table;
+ table = find_cmd(pos, match_tbl, &pos)) {
- if (*(pos - 1) == ' ') match_tbl = table->pc_sub_cmd;
- }
+ if (*(pos - 1) == ' ') match_tbl = table->pc_sub_cmd;
+ }
- return(completion_matches(text, command_generator));
+ return(completion_matches(text, command_generator));
}
/* take a string and execute the function or print help */
void execute_line(char * line)
{
- command_t *cmd, *ambig;
- char *prev;
- char *next, *tmp;
- char *argv[MAXARGS];
- int i;
-
- switch( process(line, &next, top_level, &cmd, &prev) ) {
- case CMD_AMBIG:
- fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line);
- while( (ambig = find_cmd(prev, cmd, &tmp)) ) {
- fprintf(stderr, "%s ", ambig->pc_name);
- cmd = ambig + 1;
- }
- fprintf(stderr, "\n");
- break;
- case CMD_NONE:
- fprintf(stderr, "No such command, type help\n");
- break;
- case CMD_INCOMPLETE:
- fprintf(stderr,
- "'%s' incomplete command. Use '%s x' where x is one of:\n",
- line, line);
- fprintf(stderr, "\t");
- for (i = 0; cmd->pc_sub_cmd[i].pc_name; i++) {
- fprintf(stderr, "%s ", cmd->pc_sub_cmd[i].pc_name);
- }
- fprintf(stderr, "\n");
- break;
- case CMD_COMPLETE:
- i = line2args(line, argv, MAXARGS);
- (cmd->pc_func)(i, argv);
- break;
- }
+ command_t *cmd, *ambig;
+ char *prev;
+ char *next, *tmp;
+ char *argv[MAXARGS];
+ int i;
+
+ switch( process(line, &next, top_level, &cmd, &prev) ) {
+ case CMD_AMBIG:
+ fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line);
+ while( (ambig = find_cmd(prev, cmd, &tmp)) ) {
+ fprintf(stderr, "%s ", ambig->pc_name);
+ cmd = ambig + 1;
+ }
+ fprintf(stderr, "\n");
+ break;
+ case CMD_NONE:
+ fprintf(stderr, "No such command, type help\n");
+ break;
+ case CMD_INCOMPLETE:
+ fprintf(stderr,
+ "'%s' incomplete command. Use '%s x' where x is one of:\n",
+ line, line);
+ fprintf(stderr, "\t");
+ for (i = 0; cmd->pc_sub_cmd[i].pc_name; i++) {
+ fprintf(stderr, "%s ", cmd->pc_sub_cmd[i].pc_name);
+ }
+ fprintf(stderr, "\n");
+ break;
+ case CMD_COMPLETE:
+ i = line2args(line, argv, MAXARGS);
+ (cmd->pc_func)(i, argv);
+ break;
+ }
- return;
+ return;
}
/* this is the command execution machine */
void Parser_commands(void)
{
- char *line,
- *s;
+ char *line,
+ *s;
- using_history();
- stifle_history(HISTORY);
+ using_history();
+ stifle_history(HISTORY);
- rl_attempted_completion_function =
- (CPPFunction *)command_completion;
- rl_completion_entry_function = (void *)command_generator;
+ rl_attempted_completion_function =
+ (CPPFunction *)command_completion;
+ rl_completion_entry_function = (void *)command_generator;
- while(!done) {
- line = readline(parser_prompt);
+ while(!done) {
+ line = readline(parser_prompt);
- if (!line) break;
+ if (!line) break;
- s = skipwhitespace(line);
+ s = skipwhitespace(line);
- if (*s) {
- add_history(s);
- execute_line(s);
- }
+ if (*s) {
+ add_history(s);
+ execute_line(s);
+ }
- free(line);
- }
+ free(line);
+ }
}
/* sets the parser prompt */
void Parser_init(char * prompt, command_t * cmds)
{
- done = 0;
- top_level = cmds;
- if (parser_prompt) free(parser_prompt);
- parser_prompt = strdup(prompt);
+ done = 0;
+ top_level = cmds;
+ if (parser_prompt) free(parser_prompt);
+ parser_prompt = strdup(prompt);
}
/* frees the parser prompt */
void Parser_exit(int argc, char *argv[])
{
- done = 1;
- free(parser_prompt);
- parser_prompt = NULL;
+ done = 1;
+ free(parser_prompt);
+ parser_prompt = NULL;
}
/* convert a string to an integer */
int Parser_int(char *s, int *val)
{
- int ret;
-
- if (*s != '0')
- ret = sscanf(s, "%d", val);
- else if (*(s+1) != 'x')
- ret = sscanf(s, "%o", val);
- else {
- s++;
- ret = sscanf(++s, "%x", val);
- }
-
- return(ret);
+ int ret;
+
+ if (*s != '0')
+ ret = sscanf(s, "%d", val);
+ else if (*(s+1) != 'x')
+ ret = sscanf(s, "%o", val);
+ else {
+ s++;
+ ret = sscanf(++s, "%x", val);
+ }
+
+ return(ret);
}
void Parser_qhelp(int argc, char *argv[]) {
- printf("Available commands are:\n");
-
- print_commands(NULL, top_level);
- printf("For more help type: help command-name\n");
+ printf("Available commands are:\n");
+
+ print_commands(NULL, top_level);
+ printf("For more help type: help command-name\n");
}
int Parser_help(int argc, char **argv)
{
- char line[1024];
- char *next, *prev, *tmp;
- command_t *result, *ambig;
- int i;
-
- if ( argc == 1 ) {
- Parser_qhelp(argc, argv);
- return 0;
- }
-
- line[0]='\0';
- for ( i = 1 ; i < argc ; i++ ) {
- strcat(line, argv[i]);
- }
-
- switch ( process(line, &next, top_level, &result, &prev) ) {
- case CMD_COMPLETE:
- fprintf(stderr, "%s: %s\n",line, result->pc_help);
- break;
- case CMD_NONE:
- fprintf(stderr, "%s: Unknown command.\n", line);
- break;
- case CMD_INCOMPLETE:
- fprintf(stderr,
- "'%s' incomplete command. Use '%s x' where x is one of:\n",
- line, line);
- fprintf(stderr, "\t");
- for (i = 0; result->pc_sub_cmd[i].pc_name; i++) {
- fprintf(stderr, "%s ", result->pc_sub_cmd[i].pc_name);
- }
- fprintf(stderr, "\n");
- break;
- case CMD_AMBIG:
- fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line);
- while( (ambig = find_cmd(prev, result, &tmp)) ) {
- fprintf(stderr, "%s ", ambig->pc_name);
- result = ambig + 1;
- }
- fprintf(stderr, "\n");
- break;
- }
- return 0;
+ char line[1024];
+ char *next, *prev, *tmp;
+ command_t *result, *ambig;
+ int i;
+
+ if ( argc == 1 ) {
+ Parser_qhelp(argc, argv);
+ return 0;
+ }
+
+ line[0]='\0';
+ for ( i = 1 ; i < argc ; i++ ) {
+ strcat(line, argv[i]);
+ }
+
+ switch ( process(line, &next, top_level, &result, &prev) ) {
+ case CMD_COMPLETE:
+ fprintf(stderr, "%s: %s\n",line, result->pc_help);
+ break;
+ case CMD_NONE:
+ fprintf(stderr, "%s: Unknown command.\n", line);
+ break;
+ case CMD_INCOMPLETE:
+ fprintf(stderr,
+ "'%s' incomplete command. Use '%s x' where x is one of:\n",
+ line, line);
+ fprintf(stderr, "\t");
+ for (i = 0; result->pc_sub_cmd[i].pc_name; i++) {
+ fprintf(stderr, "%s ", result->pc_sub_cmd[i].pc_name);
+ }
+ fprintf(stderr, "\n");
+ break;
+ case CMD_AMBIG:
+ fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line);
+ while( (ambig = find_cmd(prev, result, &tmp)) ) {
+ fprintf(stderr, "%s ", ambig->pc_name);
+ result = ambig + 1;
+ }
+ fprintf(stderr, "\n");
+ break;
+ }
+ return 0;
}
/*************************************************************************
- * COMMANDS *
+ * COMMANDS *
*************************************************************************/
static void print_commands(char * str, command_t * table) {
- command_t * cmds;
- char buf[80];
-
- for (cmds = table; cmds->pc_name; cmds++) {
- if (cmds->pc_func) {
- if (str) printf("\t%s %s\n", str, cmds->pc_name);
- else printf("\t%s\n", cmds->pc_name);
- }
- if (cmds->pc_sub_cmd) {
- if (str) {
- sprintf(buf, "%s %s", str, cmds->pc_name);
- print_commands(buf, cmds->pc_sub_cmd);
- } else {
- print_commands(cmds->pc_name, cmds->pc_sub_cmd);
- }
- }
- }
+ command_t * cmds;
+ char buf[80];
+
+ for (cmds = table; cmds->pc_name; cmds++) {
+ if (cmds->pc_func) {
+ if (str) printf("\t%s %s\n", str, cmds->pc_name);
+ else printf("\t%s\n", cmds->pc_name);
+ }
+ if (cmds->pc_sub_cmd) {
+ if (str) {
+ sprintf(buf, "%s %s", str, cmds->pc_name);
+ print_commands(buf, cmds->pc_sub_cmd);
+ } else {
+ print_commands(cmds->pc_name, cmds->pc_sub_cmd);
+ }
+ }
+ }
}
char *Parser_getstr(const char *prompt, const char *deft, char *res,
- size_t len)
+ size_t len)
{
- char *line = NULL;
- int size = strlen(prompt) + strlen(deft) + 8;
- char *theprompt;
- theprompt = malloc(size);
- assert(theprompt);
-
- sprintf(theprompt, "%s [%s]: ", prompt, deft);
-
- line = readline(theprompt);
- free(theprompt);
-
- if ( line == NULL || *line == '\0' ) {
- strncpy(res, deft, len);
- } else {
- strncpy(res, line, len);
- }
-
- if ( line ) {
- free(line);
- return res;
- } else {
- return NULL;
- }
+ char *line = NULL;
+ int size = strlen(prompt) + strlen(deft) + 8;
+ char *theprompt;
+ theprompt = malloc(size);
+ assert(theprompt);
+
+ sprintf(theprompt, "%s [%s]: ", prompt, deft);
+
+ line = readline(theprompt);
+ free(theprompt);
+
+ if ( line == NULL || *line == '\0' ) {
+ strncpy(res, deft, len);
+ } else {
+ strncpy(res, line, len);
+ }
+
+ if ( line ) {
+ free(line);
+ return res;
+ } else {
+ return NULL;
+ }
}
/* get integer from prompt, loop forever to get it */
int Parser_getint(const char *prompt, long min, long max, long deft, int base)
{
- int rc;
- long result;
- char *line;
- int size = strlen(prompt) + 40;
- char *theprompt = malloc(size);
- assert(theprompt);
- sprintf(theprompt,"%s [%ld, (0x%lx)]: ", prompt, deft, deft);
-
- fflush(stdout);
-
- do {
- line = NULL;
- line = readline(theprompt);
- if ( !line ) {
- fprintf(stdout, "Please enter an integer.\n");
- fflush(stdout);
- continue;
- }
- if ( *line == '\0' ) {
- free(line);
- result = deft;
- break;
- }
- rc = Parser_arg2int(line, &result, base);
- free(line);
- if ( rc != 0 ) {
- fprintf(stdout, "Invalid string.\n");
- fflush(stdout);
- } else if ( result > max || result < min ) {
- fprintf(stdout, "Error: response must lie between %ld and %ld.\n",
- min, max);
- fflush(stdout);
- } else {
- break;
- }
- } while ( 1 ) ;
-
- if (theprompt)
- free(theprompt);
- return result;
+ int rc;
+ long result;
+ char *line;
+ int size = strlen(prompt) + 40;
+ char *theprompt = malloc(size);
+ assert(theprompt);
+ sprintf(theprompt,"%s [%ld, (0x%lx)]: ", prompt, deft, deft);
+
+ fflush(stdout);
+
+ do {
+ line = NULL;
+ line = readline(theprompt);
+ if ( !line ) {
+ fprintf(stdout, "Please enter an integer.\n");
+ fflush(stdout);
+ continue;
+ }
+ if ( *line == '\0' ) {
+ free(line);
+ result = deft;
+ break;
+ }
+ rc = Parser_arg2int(line, &result, base);
+ free(line);
+ if ( rc != 0 ) {
+ fprintf(stdout, "Invalid string.\n");
+ fflush(stdout);
+ } else if ( result > max || result < min ) {
+ fprintf(stdout, "Error: response must lie between %ld and %ld.\n",
+ min, max);
+ fflush(stdout);
+ } else {
+ break;
+ }
+ } while ( 1 ) ;
+
+ if (theprompt)
+ free(theprompt);
+ return result;
}
/* get boolean (starting with YyNn; loop forever */
int Parser_getbool(const char *prompt, int deft)
{
- int result = 0;
- char *line;
- int size = strlen(prompt) + 8;
- char *theprompt = malloc(size);
- assert(theprompt);
+ int result = 0;
+ char *line;
+ int size = strlen(prompt) + 8;
+ char *theprompt = malloc(size);
+ assert(theprompt);
- fflush(stdout);
+ fflush(stdout);
- if ( deft != 0 && deft != 1 ) {
- fprintf(stderr, "Error: Parser_getbool given bad default (%d).\n",
- deft);
- assert ( 0 );
- }
- sprintf(theprompt, "%s [%s]: ", prompt, (deft==0)? "N" : "Y");
-
- do {
- line = NULL;
- line = readline(theprompt);
- if ( line == NULL ) {
- result = deft;
- break;
- }
- if ( *line == '\0' ) {
- result = deft;
- break;
- }
- if ( *line == 'y' || *line == 'Y' ) {
- result = 1;
- break;
- }
- if ( *line == 'n' || *line == 'N' ) {
- result = 0;
- break;
- }
- if ( line )
- free(line);
- fprintf(stdout, "Invalid string. Must start with yY or nN\n");
- fflush(stdout);
- } while ( 1 );
-
- if ( line )
- free(line);
- if ( theprompt )
- free(theprompt);
- return result;
+ if ( deft != 0 && deft != 1 ) {
+ fprintf(stderr, "Error: Parser_getbool given bad default (%d).\n",
+ deft);
+ assert ( 0 );
+ }
+ sprintf(theprompt, "%s [%s]: ", prompt, (deft==0)? "N" : "Y");
+
+ do {
+ line = NULL;
+ line = readline(theprompt);
+ if ( line == NULL ) {
+ result = deft;
+ break;
+ }
+ if ( *line == '\0' ) {
+ result = deft;
+ break;
+ }
+ if ( *line == 'y' || *line == 'Y' ) {
+ result = 1;
+ break;
+ }
+ if ( *line == 'n' || *line == 'N' ) {
+ result = 0;
+ break;
+ }
+ if ( line )
+ free(line);
+ fprintf(stdout, "Invalid string. Must start with yY or nN\n");
+ fflush(stdout);
+ } while ( 1 );
+
+ if ( line )
+ free(line);
+ if ( theprompt )
+ free(theprompt);
+ return result;
}
/* parse int out of a string or prompt for it */
long Parser_intarg(const char *inp, const char *prompt, int deft,
- int min, int max, int base)
+ int min, int max, int base)
{
- long result;
- int rc;
+ long result;
+ int rc;
- rc = Parser_arg2int(inp, &result, base);
+ rc = Parser_arg2int(inp, &result, base);
- if ( rc == 0 ) {
- return result;
- } else {
- return Parser_getint(prompt, deft, min, max, base);
- }
+ if ( rc == 0 ) {
+ return result;
+ } else {
+ return Parser_getint(prompt, deft, min, max, base);
+ }
}
/* parse int out of a string or prompt for it */
char *Parser_strarg(char *inp, const char *prompt, const char *deft,
- char *answer, int len)
+ char *answer, int len)
{
- if ( inp == NULL || *inp == '\0' ) {
- return Parser_getstr(prompt, deft, answer, len);
- } else
- return inp;
+ if ( inp == NULL || *inp == '\0' ) {
+ return Parser_getstr(prompt, deft, answer, len);
+ } else
+ return inp;
}
/* change a string into a number: return 0 on success. No invalid characters
allowed. The processing of base and validity follows strtol(3)*/
int Parser_arg2int(const char *inp, long *result, int base)
{
- char *endptr;
+ char *endptr;
- if ( (base !=0) && (base < 2 || base > 36) )
- return 1;
+ if ( (base !=0) && (base < 2 || base > 36) )
+ return 1;
- *result = strtol(inp, &endptr, base);
+ *result = strtol(inp, &endptr, base);
- if ( *inp != '\0' && *endptr == '\0' )
- return 0;
- else
- return 1;
+ if ( *inp != '\0' && *endptr == '\0' )
+ return 0;
+ else
+ return 1;
}
int Parser_quit(int argc, char **argv)
{
- argc = argc;
- argv = argv;
- done = 1;
- return 0;
+ argc = argc;
+ argv = argv;
+ done = 1;
+ return 0;
}