-/*
- * This Cplant(TM) source code is the property of Sandia National
- * Laboratories.
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
*
- * This Cplant(TM) source code is copyrighted by Sandia National
- * Laboratories.
+ * Lustre Light user test program
*
- * The redistribution of this Cplant(TM) source code is subject to the
- * terms of the GNU Lesser General Public License
- * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html)
+ * Copyright (c) 2002, 2003 Cluster File Systems, Inc.
*
- * Cplant(TM) Copyright 1998-2003 Sandia Corporation.
- * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
- * license for use of this work by or on behalf of the US Government.
- * Export of this program may require a license from the United States
- * Government.
- */
-
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This file is part of Lustre, http://www.lustre.org.
*
- * Questions or comments about this library should be sent to:
+ * 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.
*
- * Lee Ward
- * Sandia National Laboratories, New Mexico
- * P.O. Box 5800
- * Albuquerque, NM 87185-1110
+ * 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.
*
- * lee@sandia.gov
+ * 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 _BSD_SOURCE
#include <mount.h>
+int do_stat(const char *name)
+{
+ struct stat stat;
+
+ if (lstat(name, &stat)) {
+ perror("failed to stat: ");
+ return -1;
+ }
+ printf("******* stat '%s' ********\n", name);
+ printf("ino:\t\t%lu\n",stat.st_ino);
+ printf("mode:\t\t%o\n",stat.st_mode);
+ printf("nlink:\t\t%d\n",stat.st_nlink);
+ printf("uid/gid:\t%d/%d\n", stat.st_uid, stat.st_gid);
+ printf("size:\t\t%ld\n", stat.st_size);
+ printf("blksize:\t%ld\n", stat.st_blksize);
+ printf("block count:\t%ld\n", stat.st_blocks);
+ printf("atime:\t\t%lu\n",stat.st_atime);
+ printf("mtime:\t\t%lu\n",stat.st_mtime);
+ printf("ctime:\t\t%lu\n",stat.st_ctime);
+ printf("******* end stat ********\n");
+
+ return 0;
+}
/*
* Get stats of file and file system.
*
main(int argc, char * const argv[])
{
struct stat statbuf;
- int err, i, fd, written, readed;
+ int rc, err, i, fd, written, readed;
char pgbuf[4096], readbuf[4096];
int npages;
printf("******** end stat %s: %d*********\n", files[i], err);
}
#endif
-#if 1
+#if 0
portal_debug = 0;
portal_subsystem_debug = 0;
- npages = 100;
+ npages = 10;
fd = open("/newfile01", O_RDWR|O_CREAT|O_TRUNC, 00664);
printf("***************** open return %d ****************\n", fd);
readbuf[10] = 0;
printf("<<< page %d: %d bytes (%s)\n", i, readed, readbuf);
}
+ close(fd);
#endif
+
+#if 1
+ //rc = chown("/newfile01", 10, 20);
+ rc = chmod("/newfile01", 0777);
+ printf("-------------- chmod return %d -----------\n", rc);
+ do_stat("/newfile01");
+#endif
+
printf("sysio is about shutdown\n");
/*
* Clean up.
#include <string.h>
#include <error.h>
#include <assert.h>
+#include <time.h>
#include <sys/types.h>
#include <sys/queue.h>
return -EINVAL;
/* mdc_getattr_name require NULL-terminated name */
- pname = malloc(name->len + 1);
+ OBD_ALLOC(pname, name->len + 1);
if (!pname)
return -ENOMEM;
memcpy(pname, name->name, name->len);
out:
ptlrpc_req_finished(request);
+ OBD_FREE(pname, name->len + 1);
return rc;
}
OBD_FREE(lli, sizeof(*lli));
}
+static int llu_setattr_raw(struct inode *inode, struct iattr *attr)
+{
+ struct ptlrpc_request *request = NULL;
+ struct llu_sb_info *sbi = llu_i2sbi(inode);
+ struct llu_inode_info *lli = llu_i2info(inode);
+ struct mdc_op_data op_data;
+ int err = 0;
+ ENTRY;
+ CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", lli->lli_st_ino);
+
+ /* if need truncate, do it at first */
+ if (attr->ia_valid & ATTR_SIZE) {
+ printf("************* don't support truncate now !!!!!!!!\n");
+ LBUG();
+ }
+
+ /* Don't send size changes to MDS to avoid "fast EA" problems, and
+ * also avoid a pointless RPC (we get file size from OST anyways).
+ */
+ attr->ia_valid &= ~ATTR_SIZE;
+ if (!attr->ia_valid)
+ RETURN(0);
+
+ llu_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0);
+
+ err = mdc_setattr(&sbi->ll_mdc_conn, &op_data,
+ attr, NULL, 0, &request);
+ if (err)
+ CERROR("mdc_setattr fails: err = %d\n", err);
+
+ ptlrpc_req_finished(request);
+
+ if (S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_MTIME_SET) {
+ struct lov_stripe_md *lsm = lli->lli_smd;
+ struct obdo oa;
+ int err2;
+
+ CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n",
+ lli->lli_st_ino, attr->ia_mtime);
+ oa.o_id = lsm->lsm_object_id;
+ oa.o_mode = S_IFREG;
+ oa.o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLMTIME;
+ oa.o_mtime = attr->ia_mtime;
+ err2 = obd_setattr(&sbi->ll_osc_conn, &oa, lsm, NULL);
+ if (err2) {
+ CERROR("obd_setattr fails: rc=%d\n", err);
+ if (!err)
+ err = err2;
+ }
+ }
+ RETURN(err);
+}
+
+/* FIXME here we simply act as a thin layer to glue it with
+ * llu_setattr_raw(), which is copy from kernel
+ */
+static int llu_iop_setattr(struct pnode *pno,
+ struct inode *ino,
+ unsigned mask,
+ struct intnl_stat *stbuf)
+{
+ struct iattr iattr;
+
+ memset(&iattr, 0, sizeof(iattr));
+
+ if (mask & SETATTR_MODE) {
+ iattr.ia_mode = stbuf->st_mode;
+ iattr.ia_valid |= ATTR_MODE;
+ }
+ if (mask & SETATTR_MTIME) {
+ iattr.ia_mtime = stbuf->st_mtime;
+ iattr.ia_valid |= ATTR_MTIME;
+ }
+ if (mask & SETATTR_ATIME) {
+ iattr.ia_atime = stbuf->st_atime;
+ iattr.ia_valid |= ATTR_ATIME;
+ }
+ if (mask & SETATTR_UID) {
+ iattr.ia_uid = stbuf->st_uid;
+ iattr.ia_valid |= ATTR_UID;
+ }
+ if (mask & SETATTR_GID) {
+ iattr.ia_gid = stbuf->st_gid;
+ iattr.ia_valid |= ATTR_GID;
+ }
+ if (mask & SETATTR_LEN) {
+ iattr.ia_size = stbuf->st_size; /* FIXME signed expansion problem */
+ iattr.ia_valid |= ATTR_SIZE;
+ }
+
+ iattr.ia_valid |= ATTR_RAW;
+ /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME
+ * without ATTR_FROM_OPEN, mds_reint_setattr will call
+ * mds_fid2locked_dentry() and deadlocked at completion_ast call.
+ * Here we workaround it and avoid any locking.
+ * FIXME FIXME FIXME FIXME FIXME FIXME FIXME
+ */
+ iattr.ia_valid |= ATTR_FROM_OPEN;
+
+ return llu_setattr_raw(ino, &iattr);
+}
+
+
+static int llu_mkdir2(struct inode *dir, const char *name, int len, int mode)
+{
+ struct ptlrpc_request *request = NULL;
+ time_t curtime = CURRENT_TIME;
+ struct llu_sb_info *sbi = llu_i2sbi(dir);
+ struct llu_inode_info *lli = llu_i2info(dir);
+ struct mdc_op_data op_data;
+ int err = -EMLINK;
+ ENTRY;
+ CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu\n",
+ name, lli->lli_st_ino);
+
+ /* FIXME check this later */
+#if 0
+ if (dir->i_nlink >= EXT2_LINK_MAX)
+ RETURN(err);
+ mode = (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask) | S_IFDIR;
+#endif
+ mode |= S_IFDIR;
+ llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
+ err = mdc_create(&sbi->ll_mdc_conn, &op_data, NULL, 0, mode,
+ current->fsuid, current->fsgid,
+ curtime, 0, &request);
+ ptlrpc_req_finished(request);
+ RETURN(err);
+}
+
+static int llu_iop_mkdir(struct pnode *pno, mode_t mode)
+{
+ struct inode *dir = pno->p_base->pb_parent->pb_ino;
+ struct qstr *qstr = &pno->p_base->pb_name;
+ int rc;
+
+ LASSERT(dir);
+
+ rc = llu_mkdir2(dir, qstr->name, qstr->len, mode);
+
+ return rc;
+}
+
+#ifndef S_IRWXUGO
+#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
+#endif
+
+static int llu_symlink2(struct inode *dir, const char *name, int len,
+ const char *tgt)
+{
+ struct ptlrpc_request *request = NULL;
+ time_t curtime = CURRENT_TIME;
+ struct llu_sb_info *sbi = llu_i2sbi(dir);
+ struct llu_inode_info *lli = llu_i2info(dir);
+ struct mdc_op_data op_data;
+ int err = -EMLINK;
+ ENTRY;
+
+ CDEBUG(D_VFSTRACE, "VFS Op:name=%s,dir=%lu,target=%s\n",
+ name, lli->lli_st_ino, tgt);
+
+#if 0
+ if (dir->i_nlink >= EXT2_LINK_MAX)
+ RETURN(err);
+#endif
+ llu_prepare_mdc_op_data(&op_data, dir, NULL, name, len, 0);
+ err = mdc_create(&sbi->ll_mdc_conn, &op_data,
+ tgt, strlen(tgt) + 1, S_IFLNK | S_IRWXUGO,
+ current->fsuid, current->fsgid, curtime, 0, &request);
+ ptlrpc_req_finished(request);
+ RETURN(err);
+}
+
+static int llu_iop_symlink(struct pnode *pno, const char *data)
+{
+ struct inode *dir = pno->p_base->pb_parent->pb_ino;
+ struct qstr *qstr = &pno->p_base->pb_name;
+ int rc;
+
+ LASSERT(dir);
+
+ rc = llu_symlink2(dir, qstr->name, qstr->len, data);
+
+ return rc;
+}
+
struct filesys_ops llu_filesys_ops =
{
fsop_gone: llu_fsop_gone,
static struct inode_ops llu_inode_ops = {
inop_lookup: llu_iop_lookup,
inop_getattr: llu_iop_getattr,
+ inop_setattr: llu_iop_setattr,
+ inop_getdirentries: NULL,
+ inop_mkdir: llu_iop_mkdir,
+ inop_rmdir: NULL,
+ inop_symlink: llu_iop_symlink,
+ inop_readlink: NULL,
inop_open: llu_iop_open,
inop_close: llu_iop_close,
+ inop_unlink: NULL,
inop_ipreadv: llu_iop_ipreadv,
inop_ipwritev: llu_iop_ipwritev,
inop_iodone: llu_iop_iodone,
+ inop_fcntl: NULL,
+ inop_sync: NULL,
+ inop_datasync: NULL,
+ inop_ioctl: NULL,
+ inop_mknod: NULL,
+ inop_statvfs: NULL,
inop_gone: llu_iop_gone,
};