From ec417e23307b411a0a8bc9bf9f78c34d35e42071 Mon Sep 17 00:00:00 2001 From: braam Date: Sat, 9 Mar 2002 18:31:38 +0000 Subject: [PATCH] - add open and close calls: initial purpose is to support I/O to open, unlinked files - fix faulty connection handling in osc/ost methods: unlink, punch (this should explain and fix the iozone behavior). --- lustre/include/linux/lustre_idl.h | 3 +- lustre/include/linux/lustre_light.h | 7 ++- lustre/include/linux/lustre_mds.h | 4 ++ lustre/include/linux/obd_class.h | 23 +++++++++ lustre/include/linux/obd_support.h | 10 ++-- lustre/llite/file.c | 98 +++++++++++++++++++++++++++++++++++++ lustre/llite/super.c | 7 +++ lustre/mdc/mdc_request.c | 2 + lustre/mds/handler.c | 33 +++++++++++++ lustre/osc/osc_request.c | 75 ++++++++++++++++++++++++++++ lustre/ost/ost_handler.c | 59 ++++++++++++++++++++++ 11 files changed, 314 insertions(+), 7 deletions(-) diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index 0ae4f85..9e50ef7 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -56,7 +56,8 @@ #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 diff --git a/lustre/include/linux/lustre_light.h b/lustre/include/linux/lustre_light.h index edb38fb..b290ae6 100644 --- a/lustre/include/linux/lustre_light.h +++ b/lustre/include/linux/lustre_light.h @@ -16,7 +16,11 @@ #include #include -#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 { @@ -25,6 +29,7 @@ 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; diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h index 7616bcb..a958168 100644 --- a/lustre/include/linux/lustre_mds.h +++ b/lustre/include/linux/lustre_mds.h @@ -103,6 +103,10 @@ int mdc_getattr(struct ptlrpc_client *peer, ino_t ino, int type, int valid, 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, diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 1ad5477..beed87c 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -137,6 +137,8 @@ struct obd_ops { 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, @@ -325,6 +327,27 @@ static inline int obd_getattr(struct obd_conn *conn, struct obdo *obdo) 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; diff --git a/lustre/include/linux/obd_support.h b/lustre/include/linux/obd_support.h index 4aeeaa5..17d84a0 100644 --- a/lustre/include/linux/obd_support.h +++ b/lustre/include/linux/obd_support.h @@ -19,23 +19,23 @@ extern unsigned long obd_memory; #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 diff --git a/lustre/llite/file.c b/lustre/llite/file.c index d35a8f7..da2b218 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -41,6 +41,101 @@ 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; @@ -56,6 +151,7 @@ static inline void ll_remove_suid(struct inode *inode) } } + /* * Write to a file (through the page cache). */ @@ -92,6 +188,8 @@ int ll_fsync(struct file *file, struct dentry *dentry, int data) 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 }; diff --git a/lustre/llite/super.c b/lustre/llite/super.c index 2d630cb..eb52c7d 100644 --- a/lustre/llite/super.c +++ b/lustre/llite/super.c @@ -36,6 +36,7 @@ #include #include +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; @@ -403,6 +404,11 @@ struct file_system_type lustre_light_fs_type = { 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); } @@ -410,6 +416,7 @@ static int __init init_lustre_light(void) 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 "); diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index cb8a4db..534ee5a 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -351,6 +351,8 @@ EXPORT_SYMBOL(mdc_link); 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); diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index a626e5b..5c60347 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -250,6 +250,39 @@ int mds_open(struct ptlrpc_request *req) 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) { diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 2804474..307bf76 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -123,6 +123,7 @@ static int osc_getattr(struct obd_conn *conn, struct obdo *oa) } 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); @@ -143,6 +144,75 @@ static int osc_getattr(struct obd_conn *conn, struct obdo *oa) 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; @@ -156,6 +226,7 @@ static int osc_setattr(struct obd_conn *conn, struct obdo *oa) } 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); @@ -220,6 +291,7 @@ static int osc_punch(struct obd_conn *conn, struct obdo *oa, obd_size 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_req.ost->oa.o_size = offset; request->rq_req.ost->oa.o_blocks = count; @@ -254,6 +326,7 @@ static int osc_destroy(struct obd_conn *conn, struct obdo *oa) } 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); @@ -530,6 +603,8 @@ struct obd_ops osc_obd_ops = { 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, diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index cdd5245..b81caf1 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -101,6 +101,57 @@ static int ost_getattr(struct ost_obd *ost, struct ptlrpc_request *req) 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; @@ -582,6 +633,14 @@ static int ost_handle(struct obd_device *obddev, 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); -- 1.8.3.1