X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fliblustre%2Ffile.c;h=f30cdaf3561f57791ca6cd3966c12f0bb61b7e3a;hb=7c649f5cc51ecd58722e5948bd27092a85ce218b;hp=34706f34c8087e7ca085005226be60916f9229ea;hpb=c1f6b32958c799412c830f35f8d16ed7275407ea;p=fs%2Flustre-release.git diff --git a/lustre/liblustre/file.c b/lustre/liblustre/file.c index 34706f3..f30cdaf 100644 --- a/lustre/liblustre/file.c +++ b/lustre/liblustre/file.c @@ -1,24 +1,41 @@ /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * - * Lustre Light file operations + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * Copyright (c) 2002-2004 Cluster File Systems, Inc. + * This program 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 version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). * - * This file is part of Lustre, http://www.lustre.org. + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf * - * 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. + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * GPL HEADER END + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. * - * 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. + * lustre/liblustre/file.c * - * 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. + * Lustre Light file operations */ #define DEBUG_SUBSYSTEM S_LLITE @@ -120,10 +137,10 @@ void obdo_refresh_inode(struct inode *dst, if (valid & OBD_MD_FLATIME && src->o_atime > LTIME_S(st->st_atime)) LTIME_S(st->st_atime) = src->o_atime; - + /* mtime is always updated with ctime, but can be set in past. As write and utime(2) may happen within 1 second, and utime's - mtime has a priority over write's one, leave mtime from mds + mtime has a priority over write's one, leave mtime from mds for the same ctimes. */ if (valid & OBD_MD_FLCTIME && src->o_ctime > LTIME_S(st->st_ctime)) { LTIME_S(st->st_ctime) = src->o_ctime; @@ -140,6 +157,15 @@ void obdo_refresh_inode(struct inode *dst, st->st_blocks = src->o_blocks; } +void llu_ioepoch_open(struct llu_inode_info *lli, __u64 ioepoch) +{ + if (ioepoch && lli->lli_ioepoch != ioepoch) { + lli->lli_ioepoch = ioepoch; + CDEBUG(D_INODE, "Epoch "LPU64" opened on "DFID" for truncate\n", + ioepoch, PFID(&lli->lli_fid)); + } +} + int llu_local_open(struct llu_inode_info *lli, struct lookup_intent *it) { struct ptlrpc_request *req = it->d.lustre.it_data; @@ -165,7 +191,7 @@ int llu_local_open(struct llu_inode_info *lli, struct lookup_intent *it) fd->fd_mds_och.och_magic = OBD_CLIENT_HANDLE_MAGIC; fd->fd_mds_och.och_fid = lli->lli_fid; lli->lli_file_data = fd; - + llu_ioepoch_open(lli, body->ioepoch); md_set_open_replay_data(lli->lli_sbi->ll_md_exp, &fd->fd_mds_och, it->d.lustre.it_data); @@ -211,14 +237,9 @@ int llu_iop_open(struct pnode *pnode, int flags, mode_t mode) fd = lli->lli_file_data; lsm = lli->lli_smd; - if (lsm == NULL) { - if (fd->fd_flags & O_LOV_DELAY_CREATE) { - CDEBUG(D_INODE, "object creation was delayed\n"); - GOTO(out_release, rc); - } - } - fd->fd_flags &= ~O_LOV_DELAY_CREATE; - + if (lsm) + flags &= ~O_LOV_DELAY_CREATE; + /*XXX: open_flags are overwritten and the previous ones are lost */ lli->lli_open_flags = flags & ~(O_CREAT | O_EXCL | O_TRUNC); out_release: @@ -303,7 +324,7 @@ int llu_objects_destroy(struct ptlrpc_request *req, struct inode *dir) } } - rc = obd_destroy(llu_i2obdexp(dir), oa, lsm, &oti, NULL); + rc = obd_destroy(llu_i2obdexp(dir), oa, lsm, &oti, NULL, NULL); OBDO_FREE(oa); if (rc) CERROR("obd destroy objid 0x"LPX64" error %d\n", @@ -314,19 +335,19 @@ int llu_objects_destroy(struct ptlrpc_request *req, struct inode *dir) return rc; } -int llu_sizeonmds_update(struct inode *inode, struct md_open_data *mod, - struct lustre_handle *fh, __u64 ioepoch) +int llu_sizeonmds_update(struct inode *inode, struct lustre_handle *fh, + __u64 ioepoch) { struct llu_inode_info *lli = llu_i2info(inode); struct llu_sb_info *sbi = llu_i2sbi(inode); struct md_op_data op_data = {{ 0 }}; - struct obdo oa; + struct obdo oa = { 0 }; int rc; ENTRY; - + LASSERT(!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)); LASSERT(sbi->ll_lco.lco_flags & OBD_CONNECT_SOM); - + rc = llu_inode_getattr(inode, &oa); if (rc == -ENOENT) { oa.o_valid = 0; @@ -339,13 +360,13 @@ int llu_sizeonmds_update(struct inode *inode, struct md_open_data *mod, lli->lli_st_generation); RETURN(rc); } - + md_from_obdo(&op_data, &oa, oa.o_valid); memcpy(&op_data.op_handle, fh, sizeof(*fh)); op_data.op_ioepoch = ioepoch; op_data.op_flags |= MF_SOM_CHANGE; - rc = llu_md_setattr(inode, &op_data, &mod); + rc = llu_md_setattr(inode, &op_data, NULL); RETURN(rc); } @@ -357,21 +378,17 @@ int llu_md_close(struct obd_export *md_exp, struct inode *inode) struct obd_client_handle *och = &fd->fd_mds_och; struct intnl_stat *st = llu_i2stat(inode); struct md_op_data op_data = { { 0 } }; - int seq_end = 0, rc; + int rc; ENTRY; /* clear group lock, if present */ - if (fd->fd_flags & LL_FILE_GROUP_LOCKED) { - struct lov_stripe_md *lsm = llu_i2info(inode)->lli_smd; - fd->fd_flags &= ~(LL_FILE_GROUP_LOCKED|LL_FILE_IGNORE_LOCK); - rc = llu_extent_unlock(fd, inode, lsm, LCK_GROUP, - &fd->fd_cwlockh); - } + if (fd->fd_flags & LL_FILE_GROUP_LOCKED) + llu_put_grouplock(inode, fd->fd_grouplock.cg_gid); op_data.op_attr.ia_valid = ATTR_MODE | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_CTIME_SET; - - if (fd->fd_flags & FMODE_WRITE) { + + if (lli->lli_open_flags & FMODE_WRITE) { struct llu_sb_info *sbi = llu_i2sbi(inode); if (!(sbi->ll_lco.lco_flags & OBD_CONNECT_SOM) || !S_ISREG(llu_i2stat(inode)->st_mode)) { @@ -383,11 +400,11 @@ int llu_md_close(struct obd_export *md_exp, struct inode *inode) * are really changed. */ op_data.op_flags |= MF_SOM_CHANGE; - /* Pack Size-on-MDS attributes if we are in IO epoch and + /* Pack Size-on-MDS attributes if we are in IO epoch and * attributes are valid. */ LASSERT(!(lli->lli_flags & LLIF_MDS_SIZE_LOCK)); - if (!llu_local_size(inode)) - op_data.op_attr.ia_valid |= + if (!cl_local_size(inode)) + op_data.op_attr.ia_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS; } } @@ -402,14 +419,11 @@ int llu_md_close(struct obd_export *md_exp, struct inode *inode) memcpy(&op_data.op_handle, &och->och_fh, sizeof(op_data.op_handle)); rc = md_close(md_exp, &op_data, och->och_mod, &req); - if (rc != -EAGAIN) - seq_end = 1; - if (rc == -EAGAIN) { /* We are the last writer, so the MDS has instructed us to get * the file size and any write cookies, then close again. */ - LASSERT(fd->fd_flags & FMODE_WRITE); - rc = llu_sizeonmds_update(inode, och->och_mod, &och->och_fh, + LASSERT(lli->lli_open_flags & FMODE_WRITE); + rc = llu_sizeonmds_update(inode, &och->och_fh, op_data.op_ioepoch); if (rc) { CERROR("inode %llu mdc Size-on-MDS update failed: " @@ -426,8 +440,6 @@ int llu_md_close(struct obd_export *md_exp, struct inode *inode) (long long)st->st_ino, rc); } - if (seq_end) - ptlrpc_close_replay_seq(req); md_clear_open_replay_data(md_exp, och); ptlrpc_req_finished(req); och->och_fh.cookie = DEAD_HANDLE_MAGIC; @@ -496,71 +508,3 @@ _SYSIO_OFF_T llu_iop_pos(struct inode *ino, _SYSIO_OFF_T off) RETURN(off); } - -/* this isn't where truncate starts. roughly: - * llu_iop_{open,setattr}->llu_setattr_raw->llu_vmtruncate->llu_truncate - * we grab the lock back in setattr_raw to avoid races. */ -static void llu_truncate(struct inode *inode, obd_flag flags) -{ - struct llu_inode_info *lli = llu_i2info(inode); - struct intnl_stat *st = llu_i2stat(inode); - struct obd_info oinfo = { { { 0 } } }; - struct obdo oa = { 0 }; - int rc; - ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op:inode=%llu/%lu(%p) to %llu\n", - (long long)st->st_ino, lli->lli_st_generation, inode, - (long long)st->st_size); - - if (!lli->lli_smd) { - CDEBUG(D_INODE, "truncate on inode %llu with no objects\n", - (long long)st->st_ino); - EXIT; - return; - } - - oinfo.oi_md = lli->lli_smd; - oinfo.oi_policy.l_extent.start = st->st_size; - oinfo.oi_policy.l_extent.end = OBD_OBJECT_EOF; - oinfo.oi_oa = &oa; - oa.o_id = lli->lli_smd->lsm_object_id; - oa.o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS; - oa.o_flags = flags; /* We don't actually want to copy inode flags */ - - obdo_from_inode(&oa, inode, - OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLATIME | - OBD_MD_FLMTIME | OBD_MD_FLCTIME); - - obd_adjust_kms(llu_i2obdexp(inode), lli->lli_smd, st->st_size, 1); - - CDEBUG(D_INFO, "calling punch for "LPX64" (all bytes after %Lu)\n", - oa.o_id, (long long)st->st_size); - - /* truncate == punch from new size to absolute end of file */ - rc = obd_punch_rqset(llu_i2obdexp(inode), &oinfo, NULL); - if (rc) - CERROR("obd_truncate fails (%d) ino %llu\n", - rc, (long long)st->st_ino); - else - obdo_to_inode(inode, &oa, OBD_MD_FLSIZE | OBD_MD_FLBLOCKS | - OBD_MD_FLATIME | OBD_MD_FLMTIME | - OBD_MD_FLCTIME); - - EXIT; - return; -} /* llu_truncate */ - -int llu_vmtruncate(struct inode * inode, loff_t offset, obd_flag flags) -{ - llu_i2stat(inode)->st_size = offset; - - /* - * llu_truncate() is only called from this - * point. llu_vmtruncate/llu_truncate split exists to mimic the - * structure of Linux VFS truncate code path. - */ - - llu_truncate(inode, flags); - - return 0; -}