From: nfshp Date: Thu, 3 Apr 2003 16:48:24 +0000 (+0000) Subject: initially add open support. Now it didn't involed ldlm, just simply X-Git-Tag: v1_7_100~1^94~31 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=5d857835176e7066b14dca010db85c3263f193fa;p=fs%2Flustre-release.git initially add open support. Now it didn't involed ldlm, just simply create object on mds/ost. --- diff --git a/lustre/liblustre/file.c b/lustre/liblustre/file.c new file mode 100644 index 0000000..9a97c16 --- /dev/null +++ b/lustre/liblustre/file.c @@ -0,0 +1,377 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Lustre Light Super operations + * + * Copyright (c) 2002, 2003 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.lustre.org. + * + * 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. + */ + +#define DEBUG_SUBSYSTEM S_LLITE + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "llite_lib.h" + +void llu_prepare_mdc_op_data(struct mdc_op_data *data, + struct inode *i1, + struct inode *i2, + const char *name, + int namelen, + int mode) +{ + struct llu_inode_info *lli1, *lli2; + + LASSERT(i1); + + lli1 = llu_i2info(i1); + data->ino1 = lli1->lli_st_ino; + data->gen1 = lli1->lli_st_generation; + data->typ1 = lli1->lli_st_mode & S_IFMT; + data->gid1 = lli1->lli_st_gid; + + if (i2) { + lli2 = llu_i2info(i2); + data->ino2 = lli2->lli_st_ino; + data->gen2 = lli2->lli_st_generation; + data->typ2 = lli2->lli_st_mode & S_IFMT; + data->gid2 = lli2->lli_st_gid; + } else + data->ino2 = 0; + + data->name = name; + data->namelen = namelen; + data->mode = mode; +} + +static struct inode *llu_create_node(struct inode *dir, const char *name, + int namelen, const void *data, int datalen, + int mode, __u64 extra, + struct lookup_intent *it) +{ + struct inode *inode; + struct ptlrpc_request *request = NULL; + struct mds_body *body; + time_t time = 123456;//time(NULL); + struct llu_sb_info *sbi = llu_i2sbi(dir); + + if (it && it->it_disposition) { + LBUG(); +#if 0 + ll_invalidate_inode_pages(dir); +#endif + request = it->it_data; + body = lustre_msg_buf(request->rq_repmsg, 1); + } else { + struct mdc_op_data op_data; + struct llu_inode_info *lli_dir = llu_i2info(dir); + int gid = current->fsgid; + int rc; + + if (lli_dir->lli_st_mode & S_ISGID) { + gid = lli_dir->lli_st_gid; + if (S_ISDIR(mode)) + mode |= S_ISGID; + } + + llu_prepare_mdc_op_data(&op_data, dir, NULL, name, namelen, 0); + rc = mdc_create(&sbi->ll_mdc_conn, &op_data, + data, datalen, mode, current->fsuid, gid, + time, extra, &request); + if (rc) { + inode = (struct inode*)rc; + goto out; + } + body = lustre_msg_buf(request->rq_repmsg, 0); + } + + inode = llu_new_inode(dir->i_fs, body->ino, body->mode); + if (!inode) { + /* FIXME more cleanup needed? */ + goto out; + } + + llu_update_inode(inode, body, NULL); + + if (it && it->it_disposition) { + /* We asked for a lock on the directory, but were + * granted a lock on the inode. Since we finally have + * an inode pointer, stuff it in the lock. */ +#if 0 + ll_mdc_lock_set_inode((struct lustre_handle *)it->it_lock_handle, + inode); +#endif + } + + out: + ptlrpc_req_finished(request); + return inode; +} + +int llu_create(struct inode *dir, struct pnode_base *pnode, int mode) +{ + struct inode *inode; + int rc = 0; + +#if 0 + CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu,intent=%s\n", + dentry->d_name.name, dir->i_ino, LL_IT2STR(dentry->d_it)); + + it = dentry->d_it; + + rc = ll_it_open_error(IT_OPEN_CREATE, it); + if (rc) { + LL_GET_INTENT(dentry, it); + ptlrpc_req_finished(it->it_data); + RETURN(rc); + } +#endif + inode = llu_create_node(dir, pnode->pb_name.name, pnode->pb_name.len, + NULL, 0, mode, 0, NULL); + + if (IS_ERR(inode)) + RETURN(PTR_ERR(inode)); + + pnode->pb_ino = inode; + + return 0; +} + +static int llu_create_obj(struct lustre_handle *conn, struct inode *inode, + struct lov_stripe_md *lsm) +{ + struct ptlrpc_request *req = NULL; + struct llu_inode_info *lli = llu_i2info(inode); + struct lov_mds_md *lmm = NULL; + struct obdo *oa; + struct iattr iattr; + struct mdc_op_data op_data; + int rc, err, lmm_size = 0;; + ENTRY; + + oa = obdo_alloc(); + if (!oa) + RETURN(-ENOMEM); + + oa->o_mode = S_IFREG | 0600; + oa->o_id = lli->lli_st_ino; + /* Keep these 0 for now, because chown/chgrp does not change the + * ownership on the OST, and we don't want to allow BA OST NFS + * users to access these objects by mistake. + */ + oa->o_uid = 0; + oa->o_gid = 0; + oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMODE | + OBD_MD_FLUID | OBD_MD_FLGID; + + rc = obd_create(conn, oa, &lsm, NULL); + if (rc) { + CERROR("error creating objects for inode %lu: rc = %d\n", + lli->lli_st_ino, rc); + if (rc > 0) { + CERROR("obd_create returned invalid rc %d\n", rc); + rc = -EIO; + } + GOTO(out_oa, rc); + } + + LASSERT(lsm && lsm->lsm_object_id); + rc = obd_packmd(conn, &lmm, lsm); + if (rc < 0) + GOTO(out_destroy, rc); + + lmm_size = rc; + + /* Save the stripe MD with this file on the MDS */ + memset(&iattr, 0, sizeof(iattr)); + iattr.ia_valid = ATTR_FROM_OPEN; + + llu_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0); + + rc = mdc_setattr(&llu_i2sbi(inode)->ll_mdc_conn, &op_data, + &iattr, lmm, lmm_size, &req); + ptlrpc_req_finished(req); + + obd_free_wiremd(conn, &lmm); + + /* If we couldn't complete mdc_open() and store the stripe MD on the + * MDS, we need to destroy the objects now or they will be leaked. + */ + if (rc) { + CERROR("error: storing stripe MD for %lu: rc %d\n", + lli->lli_st_ino, rc); + GOTO(out_destroy, rc); + } + lli->lli_smd = lsm; + + EXIT; +out_oa: + obdo_free(oa); + return rc; + +out_destroy: + obdo_from_inode(oa, inode, OBD_MD_FLTYPE); + oa->o_id = lsm->lsm_object_id; + oa->o_valid |= OBD_MD_FLID; + err = obd_destroy(conn, oa, lsm, NULL); + obd_free_memmd(conn, &lsm); + if (err) { + CERROR("error uncreating inode %lu objects: rc %d\n", + lli->lli_st_ino, err); + } + goto out_oa; +} + +/* FIXME currently no "it" passed in */ +static int llu_local_open(struct llu_inode_info *lli, struct lookup_intent *it) +{ + struct ll_file_data *fd; +#if 0 + struct ptlrpc_request *req = it->it_data; + struct mds_body *body = lustre_msg_buf(req->rq_repmsg, 1); + ENTRY; +#endif + LASSERT(!lli->lli_file_data); + + fd = malloc(sizeof(struct ll_file_data)); + /* We can't handle this well without reorganizing ll_file_open and + * ll_mdc_close, so don't even try right now. */ + LASSERT(fd != NULL); + + memset(fd, 0, sizeof(*fd)); +#if 0 + memcpy(&fd->fd_mds_och.och_fh, &body->handle, sizeof(body->handle)); + fd->fd_mds_och.och_req = it->it_data; +#endif + lli->lli_file_data = fd; + + RETURN(0); +} + +static int llu_osc_open(struct lustre_handle *conn, struct inode *inode, + struct lov_stripe_md *lsm) +{ + struct ll_file_data *fd = llu_i2info(inode)->lli_file_data; + struct obdo *oa; + int rc; + ENTRY; + + oa = obdo_alloc(); + if (!oa) + RETURN(-ENOMEM); + oa->o_id = lsm->lsm_object_id; + oa->o_mode = S_IFREG; + oa->o_valid = (OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLBLOCKS | + OBD_MD_FLMTIME | OBD_MD_FLCTIME); + rc = obd_open(conn, oa, lsm, NULL, &fd->fd_ost_och); + if (rc) + GOTO(out, rc); + +// file->f_flags &= ~O_LOV_DELAY_CREATE; + obdo_to_inode(inode, oa, OBD_MD_FLBLOCKS | OBD_MD_FLMTIME | + OBD_MD_FLCTIME); + + EXIT; +out: + obdo_free(oa); + return rc; +} + +static int llu_file_open(struct inode *inode) +{ + struct llu_sb_info *sbi = llu_i2sbi(inode); + struct llu_inode_info *lli = llu_i2info(inode); + struct lustre_handle *conn = llu_i2obdconn(inode); + struct lookup_intent *it; + struct lov_stripe_md *lsm; + int rc = 0; + +#if 0 + CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino); + LL_GET_INTENT(file->f_dentry, it); + rc = ll_it_open_error(IT_OPEN_OPEN, it); + if (rc) + RETURN(rc); +#endif + rc = llu_local_open(lli, it); + if (rc) + LBUG(); +#if 0 + mdc_set_open_replay_data(&((struct ll_file_data *) + file->private_data)->fd_mds_och); +#endif + lsm = lli->lli_smd; + if (lsm == NULL) { +#if 0 + if (file->f_flags & O_LOV_DELAY_CREATE) { + CDEBUG(D_INODE, "delaying object creation\n"); + RETURN(0); + } +#endif + if (!lli->lli_smd) { + rc = llu_create_obj(conn, inode, NULL); + if (rc) + GOTO(out_close, rc); + } else { + CERROR("warning: stripe already set on ino %lu\n", + lli->lli_st_ino); + } + lsm = lli->lli_smd; + } + + rc = llu_osc_open(conn, inode, lsm); + if (rc) + GOTO(out_close, rc); + RETURN(0); + + out_close: +// ll_mdc_close(&sbi->ll_mdc_conn, inode, file); + return rc; +} + +int llu_iop_open(struct pnode *pnode, int flags, mode_t mode) +{ + struct inode *dir = pnode->p_parent->p_base->pb_ino; + int rc; + /* FIXME later we must add the ldlm here */ + + LASSERT(dir); + + /* libsysio forgot to guarentee mode is valid XXX */ + mode |= S_IFREG; + + if (!pnode->p_base->pb_ino) { + rc = llu_create(dir, pnode->p_base, mode); + if (rc) + return rc; + } + + LASSERT(pnode->p_base->pb_ino); + return llu_file_open(pnode->p_base->pb_ino); +} diff --git a/lustre/liblustre/llite_lib.h b/lustre/liblustre/llite_lib.h index aef0848..a454ce6 100644 --- a/lustre/liblustre/llite_lib.h +++ b/lustre/liblustre/llite_lib.h @@ -10,6 +10,12 @@ #include #include +struct ll_file_data { + struct obd_client_handle fd_mds_och; + struct obd_client_handle fd_ost_och; + __u32 fd_flags; +}; + struct llu_sb_info { struct obd_uuid ll_sb_uuid; @@ -28,6 +34,10 @@ struct llu_inode_info { unsigned long lli_flags; struct list_head lli_read_extents; + /* in libsysio we have no chance to store data in file, + * so place it here */ + struct ll_file_data *lli_file_data; + /* stat FIXME not 64 bit clean */ dev_t lli_st_dev; ino_t lli_st_ino; @@ -76,4 +86,15 @@ static inline struct lustre_handle *llu_i2obdconn(struct inode *inode) return &(llu_i2info(inode)->lli_sbi->ll_osc_conn); } +/* super.c */ +void llu_update_inode(struct inode *inode, struct mds_body *body, + struct lov_mds_md *lmm); +void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid); +void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid); +struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode); + +/* file.c */ +int llu_create(struct inode *dir, struct pnode_base *pnode, int mode); +int llu_iop_open(struct pnode *pnode, int flags, mode_t mode); + #endif diff --git a/lustre/liblustre/lltest.c b/lustre/liblustre/lltest.c index 7e65b2a..9c74a79 100644 --- a/lustre/liblustre/lltest.c +++ b/lustre/liblustre/lltest.c @@ -75,7 +75,7 @@ int main(int argc, char * const argv[]) { struct stat statbuf; - int err, i; + int err, i, fd; if (_sysio_init() != 0) { perror("init sysio"); @@ -103,6 +103,10 @@ main(int argc, char * const argv[]) printf("******** end stat %s: %d*********\n", files[i], err); } #endif +#if 1 + fd = fixme_open("/newfile", O_CREAT, 00666); + printf("***************** open return %d ****************\n", fd); +#endif printf("sysio is about shutdown\n"); /* * Clean up. diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index 02a6ca5..d5b6623 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -122,7 +122,7 @@ static void llu_fsop_gone(struct filesys *fs) static struct inode_ops llu_inode_ops; void llu_update_inode(struct inode *inode, struct mds_body *body, - struct lov_mds_md *lmm) + struct lov_mds_md *lmm) { struct llu_inode_info *lli = llu_i2info(inode); @@ -159,8 +159,7 @@ void llu_update_inode(struct inode *inode, struct mds_body *body, lli->lli_st_blocks = body->blocks; } -static void obdo_to_inode(struct inode *dst, struct obdo *src, - obd_flag valid) +void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid) { struct llu_inode_info *lli = llu_i2info(dst); @@ -196,6 +195,42 @@ static void obdo_to_inode(struct inode *dst, struct obdo *src, lli->lli_st_rdev = src->o_rdev; } +void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid) +{ + struct llu_inode_info *lli = llu_i2info(src); + + if (valid & OBD_MD_FLATIME) + dst->o_atime = LTIME_S(lli->lli_st_atime); + if (valid & OBD_MD_FLMTIME) + dst->o_mtime = LTIME_S(lli->lli_st_mtime); + if (valid & OBD_MD_FLCTIME) + dst->o_ctime = LTIME_S(lli->lli_st_ctime); + if (valid & OBD_MD_FLSIZE) + dst->o_size = lli->lli_st_size; + if (valid & OBD_MD_FLBLOCKS) /* allocation of space */ + dst->o_blocks = lli->lli_st_blocks; + if (valid & OBD_MD_FLBLKSZ) + dst->o_blksize = lli->lli_st_blksize; + if (valid & OBD_MD_FLTYPE) + dst->o_mode = (dst->o_mode & ~S_IFMT) | (lli->lli_st_mode & S_IFMT); + if (valid & OBD_MD_FLMODE) + dst->o_mode = (dst->o_mode & S_IFMT) | (lli->lli_st_mode & ~S_IFMT); + if (valid & OBD_MD_FLUID) + dst->o_uid = lli->lli_st_uid; + if (valid & OBD_MD_FLGID) + dst->o_gid = lli->lli_st_gid; + if (valid & OBD_MD_FLFLAGS) + dst->o_flags = lli->lli_st_flags; + if (valid & OBD_MD_FLNLINK) + dst->o_nlink = lli->lli_st_nlink; + if (valid & OBD_MD_FLGENER) + dst->o_generation = lli->lli_st_generation; + if (valid & OBD_MD_FLRDEV) + dst->o_rdev = (__u32)(lli->lli_st_rdev); + + dst->o_valid |= (valid & ~OBD_MD_FLID); +} + int llu_inode_getattr(struct inode *inode, struct lov_stripe_md *lsm, char *ostdata) { @@ -243,6 +278,7 @@ struct inode* llu_new_inode(struct filesys *fs, ino_t ino, mode_t mode) lli->lli_symlink_name = NULL; lli->lli_flags = 0; INIT_LIST_HEAD(&lli->lli_read_extents); + lli->lli_file_data = NULL; /* could file_identifier be 0 ? FIXME */ inode = _sysio_i_new(fs, ino, NULL, @@ -293,6 +329,7 @@ static int llu_iop_lookup(struct pnode *pnode, valid, 0, &request); if (rc < 0) { CERROR("mdc_getattr_name: %d\n", rc); + rc = -ENOENT; goto out; } body = lustre_msg_buf(request->rq_repmsg, 0); @@ -360,9 +397,11 @@ void generate_random_uuid(unsigned char uuid_out[16]) arr[i] = rand(); } + static struct inode_ops llu_inode_ops = { inop_lookup: llu_iop_lookup, inop_getattr: llu_iop_getattr, + inop_open: llu_iop_open, };