#define OST_CONNECT 7
#define OST_DISCONNECT 8
#define OST_PUNCH 9
-#define OST_BRW_COMPLETE 10
+#define OST_OPEN 10
+#define OST_CLOSE 11
/* packet types */
#define OST_TYPE_REQ 1
#include <linux/list.h>
#include <linux/lustre_net.h>
-#define LL_SUPER_MAGIC 0x0BD00BD0;
+
+extern kmem_cache_t *ll_file_data_slab;
+struct ll_file_data {
+ __u64 fd_mdshandle;
+};
#define LL_INLINESZ 60
struct ll_inode_info {
char lli_inline[LL_INLINESZ];
};
+#define LL_SUPER_MAGIC 0x0BD00BD0;
struct ll_sb_info {
struct list_head ll_list; /* list of supers */
struct obd_conn ll_conn;
struct ptlrpc_request **);
int mdc_setattr(struct ptlrpc_client *peer, struct inode *inode,
struct iattr *iattr, struct ptlrpc_request **);
+int mdc_open(struct ptlrpc_client *cl, ino_t ino, int type, int flags,
+ __u64 *fh, struct ptlrpc_request **req);
+int mdc_close(struct ptlrpc_client *cl, ino_t ino, int type, __u64 fh,
+ struct ptlrpc_request **req);
int mdc_readpage(struct ptlrpc_client *peer, ino_t ino, int type, __u64 offset,
char *addr, struct ptlrpc_request **);
int mdc_create(struct ptlrpc_client *peer,
int (*o_destroy)(struct obd_conn *conn, struct obdo *oa);
int (*o_setattr)(struct obd_conn *conn, struct obdo *oa);
int (*o_getattr)(struct obd_conn *conn, struct obdo *oa);
+ int (*o_open)(struct obd_conn *conn, struct obdo *oa);
+ int (*o_close)(struct obd_conn *conn, struct obdo *oa);
int (*o_read)(struct obd_conn *conn, struct obdo *oa, char *buf,
obd_size *count, obd_off offset);
int (*o_write)(struct obd_conn *conn, struct obdo *oa, char *buf,
return rc;
}
+static inline int obd_close(struct obd_conn *conn, struct obdo *obdo)
+{
+ int rc;
+ OBD_CHECK_SETUP(conn);
+ OBD_CHECK_OP(conn,close);
+
+ rc = OBP(conn->oc_dev, close)(conn, obdo);
+ EXIT;
+ return rc;
+}
+static inline int obd_open(struct obd_conn *conn, struct obdo *obdo)
+{
+ int rc;
+ OBD_CHECK_SETUP(conn);
+ OBD_CHECK_OP(conn,open);
+
+ rc = OBP(conn->oc_dev, open) (conn, obdo);
+ EXIT;
+ return rc;
+}
+
static inline int obd_setattr(struct obd_conn *conn, struct obdo *obdo)
{
int rc;
#define OBD_ALLOC(ptr, size) \
do { \
(ptr) = kmalloc((unsigned long)(size), GFP_KERNEL); \
- obd_memory += (size); \
- CDEBUG(D_MALLOC, "kmalloced: %ld at %x (tot %ld).\n", \
- (long)(size), (int)(ptr), obd_memory); \
- if (ptr == NULL) { \
+ if ((ptr) == NULL) { \
CERROR("kernel malloc failed at %s:%d\n", \
__FILE__, __LINE__); \
} else { \
memset((ptr), 0, (size)); \
+ obd_memory += (size); \
} \
+ CDEBUG(D_MALLOC, "kmalloced: %ld at %x (tot %ld).\n", \
+ (long)(size), (int)(ptr), obd_memory); \
} while (0)
#define OBD_FREE(ptr, size) \
do { \
kfree((ptr)); \
- obd_memory -= (size); \
CDEBUG(D_MALLOC, "kfreed: %d at %x (tot %ld).\n", \
(int)(size), (int)(ptr), obd_memory); \
+ obd_memory -= (size); \
} while (0)
#endif
extern int ll_setattr(struct dentry *de, struct iattr *attr);
+static int ll_file_open(struct inode *inode, struct file *file)
+{
+ int rc;
+ int flags = 0;
+ struct ptlrpc_request *req;
+ struct ll_file_data *fd;
+ struct obdo oa;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ ENTRY;
+
+ fd = kmem_cache_alloc(ll_file_data_slab, SLAB_KERNEL);
+ if (!fd) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ memset(&oa, 0, sizeof(oa));
+ oa.o_valid = OBD_MD_FLMODE | OBD_MD_FLID;
+ oa.o_mode = inode->i_mode;
+ oa.o_id = HTON__u64((__u64)inode->i_ino);
+ rc = obd_open(ll_i2obdconn(inode), &oa);
+ if (rc) {
+ if (rc > 0)
+ rc = -rc;
+ EXIT;
+ goto out;
+ }
+
+ rc = mdc_open(&sbi->ll_mds_client, inode->i_ino, S_IFREG, flags,
+ &fd->fd_mdshandle, &req);
+ ptlrpc_free_req(req);
+ if (rc) {
+ if (rc > 0)
+ rc = -rc;
+ EXIT;
+ goto out;
+ }
+ file->private_data = fd;
+
+ EXIT;
+ out:
+ if (rc && fd) {
+ kmem_cache_free(ll_file_data_slab, fd);
+ }
+ return rc;
+}
+
+
+static int ll_file_release(struct inode *inode, struct file *file)
+{
+ int rc;
+ struct ptlrpc_request *req;
+ struct ll_file_data *fd;
+ struct obdo oa;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ ENTRY;
+
+ fd = (struct ll_file_data *)file->private_data;
+ if (!fd) {
+ BUG();
+ goto out;
+ }
+
+ memset(&oa, 0, sizeof(oa));
+ oa.o_valid = OBD_MD_FLMODE | OBD_MD_FLID;
+ oa.o_mode = inode->i_mode;
+ oa.o_id = HTON__u64((__u64)inode->i_ino);
+ rc = obd_close(ll_i2obdconn(inode), &oa);
+ if (rc) {
+ if (rc > 0)
+ rc = -rc;
+ EXIT;
+ goto out;
+ }
+
+ rc = mdc_close(&sbi->ll_mds_client, inode->i_ino, S_IFREG,
+ fd->fd_mdshandle, &req);
+ ptlrpc_free_req(req);
+ if (rc) {
+ if (rc > 0)
+ rc = -rc;
+ EXIT;
+ goto out;
+ }
+ EXIT;
+
+ out:
+ if (!rc && fd) {
+ kmem_cache_free(ll_file_data_slab, fd);
+ file->private_data = NULL;
+ }
+ return rc;
+}
+
+
static inline void ll_remove_suid(struct inode *inode)
{
unsigned int mode;
}
}
+
/*
* Write to a file (through the page cache).
*/
struct file_operations ll_file_operations = {
read: generic_file_read,
write: ll_file_write,
+ open: ll_file_open,
+ release: ll_file_release,
mmap: generic_file_mmap,
fsync: NULL
};
#include <linux/obd_class.h>
#include <linux/lustre_light.h>
+kmem_cache_t *ll_file_data_slab;
extern struct address_space_operations ll_aops;
extern struct address_space_operations ll_dir_aops;
struct super_operations ll_super_operations;
static int __init init_lustre_light(void)
{
printk(KERN_INFO "Lustre Light 0.0.1, braam@clusterfs.com\n");
+ ll_file_data_slab = kmem_cache_create("ll_file_data",
+ sizeof(struct ll_file_data), 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (ll_file_data_slab == NULL)
+ return -ENOMEM;
return register_filesystem(&lustre_light_fs_type);
}
static void __exit exit_lustre_light(void)
{
unregister_filesystem(&lustre_light_fs_type);
+ kmem_cache_destroy(ll_file_data_slab);
}
MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
EXPORT_SYMBOL(mdc_getattr);
EXPORT_SYMBOL(mdc_readpage);
EXPORT_SYMBOL(mdc_setattr);
+EXPORT_SYMBOL(mdc_close);
+EXPORT_SYMBOL(mdc_open);
module_init(ptlrpc_request_init);
module_exit(ptlrpc_request_exit);
return 0;
}
+int mds_close(struct ptlrpc_request *req)
+{
+ struct dentry *de;
+ struct mds_rep *rep;
+ struct file *file;
+ struct vfsmount *mnt;
+ int rc;
+
+ rc = mds_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
+ &req->rq_replen, &req->rq_repbuf);
+ if (rc) {
+ EXIT;
+ CERROR("mds: out of memory\n");
+ req->rq_status = -ENOMEM;
+ return 0;
+ }
+
+ req->rq_rephdr->xid = req->rq_reqhdr->xid;
+ rep = req->rq_rep.mds;
+
+ de = mds_fid2dentry(&req->rq_obd->u.mds, &req->rq_req.mds->fid1, &mnt);
+ if (IS_ERR(de)) {
+ EXIT;
+ req->rq_rephdr->status = -ENOENT;
+ return 0;
+ }
+
+ file = (struct file *)(unsigned long) req->rq_req.mds->objid;
+ req->rq_rephdr->status = filp_close(file, 0);
+ dput(de);
+ return 0;
+}
+
int mds_readpage(struct ptlrpc_request *req)
{
}
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);
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));
+ 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));
+ }
+
+ out:
+ 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));
+ 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;
+ }
+
+ 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;
+}
+
static int osc_setattr(struct obd_conn *conn, struct obdo *oa)
{
struct ptlrpc_request *request;
}
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);
}
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;
}
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);
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,
return 0;
}
+static int ost_open(struct ost_obd *ost, struct ptlrpc_request *req)
+{
+ struct obd_conn conn;
+ int rc;
+
+ ENTRY;
+
+ conn.oc_id = req->rq_req.ost->connid;
+ conn.oc_dev = ost->ost_tgt;
+
+ rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
+ &req->rq_replen, &req->rq_repbuf);
+ if (rc) {
+ CERROR("cannot pack reply\n");
+ return rc;
+ }
+ req->rq_rep.ost->oa.o_id = req->rq_req.ost->oa.o_id;
+ req->rq_rep.ost->oa.o_valid = req->rq_req.ost->oa.o_valid;
+
+ req->rq_rep.ost->result = obd_open(&conn, &req->rq_rep.ost->oa);
+
+ EXIT;
+ return 0;
+}
+
+static int ost_close(struct ost_obd *ost, struct ptlrpc_request *req)
+{
+ struct obd_conn conn;
+ int rc;
+
+ ENTRY;
+
+ conn.oc_id = req->rq_req.ost->connid;
+ conn.oc_dev = ost->ost_tgt;
+
+ rc = ost_pack_rep(NULL, 0, NULL, 0, &req->rq_rephdr, &req->rq_rep,
+ &req->rq_replen, &req->rq_repbuf);
+ if (rc) {
+ CERROR("cannot pack reply\n");
+ return rc;
+ }
+ req->rq_rep.ost->oa.o_id = req->rq_req.ost->oa.o_id;
+ req->rq_rep.ost->oa.o_valid = req->rq_req.ost->oa.o_valid;
+
+ req->rq_rep.ost->result = obd_close(&conn, &req->rq_rep.ost->oa);
+
+ EXIT;
+ return 0;
+}
+
+
static int ost_create(struct ost_obd *ost, struct ptlrpc_request *req)
{
struct obd_conn conn;
CDEBUG(D_INODE, "setattr\n");
rc = ost_setattr(ost, req);
break;
+ case OST_OPEN:
+ CDEBUG(D_INODE, "setattr\n");
+ rc = ost_open(ost, req);
+ break;
+ case OST_CLOSE:
+ CDEBUG(D_INODE, "setattr\n");
+ rc = ost_close(ost, req);
+ break;
case OST_BRW:
CDEBUG(D_INODE, "brw\n");
rc = ost_brw(ost, req);