Whamcloud - gitweb
initially add open support. Now it didn't involed ldlm, just simply
authornfshp <nfshp>
Thu, 3 Apr 2003 16:48:24 +0000 (16:48 +0000)
committernfshp <nfshp>
Thu, 3 Apr 2003 16:48:24 +0000 (16:48 +0000)
create object on mds/ost.

lustre/liblustre/file.c [new file with mode: 0644]
lustre/liblustre/llite_lib.h
lustre/liblustre/lltest.c
lustre/liblustre/super.c

diff --git a/lustre/liblustre/file.c b/lustre/liblustre/file.c
new file mode 100644 (file)
index 0000000..9a97c16
--- /dev/null
@@ -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 <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <assert.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#include <sysio.h>
+#include <fs.h>
+#include <mount.h>
+#include <inode.h>
+#include <file.h>
+
+#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);
+}
index aef0848..a454ce6 100644 (file)
 #include <sys/types.h>
 #include <sys/stat.h>
 
+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
index 7e65b2a..9c74a79 100644 (file)
@@ -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.
index 02a6ca5..d5b6623 100644 (file)
@@ -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,
 };