📄 llite_lib.c
字号:
attr->ia_valid |= ATTR_MTIME_SET | ATTR_MTIME; attr->ia_mtime = inode->i_mtime; } if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME)) CDEBUG(D_INODE, "setting mtime %lu, ctime %lu, now = %lu\n", LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime), CURRENT_SECONDS); /* NB: ATTR_SIZE will only be set after this point if the size * resides on the MDS, ie, this file has no objects. */ if (lsm) attr->ia_valid &= ~ATTR_SIZE; /* We always do an MDS RPC, even if we're only changing the size; * only the MDS knows whether truncate() should fail with -ETXTBUSY */ ll_prepare_mdc_op_data(&op_data, inode, NULL, NULL, 0, 0, NULL); rc = mdc_setattr(sbi->ll_mdc_exp, &op_data, attr, NULL, 0, NULL, 0, &request); if (rc) { ptlrpc_req_finished(request); if (rc == -ENOENT) { inode->i_nlink = 0; /* Unlinked special device node? Or just a race? * Pretend we done everything. */ if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) rc = inode_setattr(inode, attr); } else if (rc != -EPERM && rc != -EACCES && rc != -ETXTBSY) CERROR("mdc_setattr fails: rc = %d\n", rc); RETURN(rc); } rc = mdc_req2lustre_md(request, REPLY_REC_OFF, sbi->ll_osc_exp, &md); if (rc) { ptlrpc_req_finished(request); RETURN(rc); } /* We call inode_setattr to adjust timestamps. * If there is at least some data in file, we cleared ATTR_SIZE above to * avoid invoking vmtruncate, otherwise it is important to call * vmtruncate in inode_setattr to update inode->i_size (bug 6196) */ rc = inode_setattr(inode, attr); ll_update_inode(inode, &md); ptlrpc_req_finished(request); if (!lsm || !S_ISREG(inode->i_mode)) { CDEBUG(D_INODE, "no lsm: not setting attrs on OST\n"); RETURN(rc); } /* We really need to get our PW lock before we change inode->i_size. * If we don't we can race with other i_size updaters on our node, like * ll_file_read. We can also race with i_size propogation to other * nodes through dirtying and writeback of final cached pages. This * last one is especially bad for racing o_append users on other * nodes. */ if (ia_valid & ATTR_SIZE) { rc = ll_setattr_do_truncate(inode, attr->ia_size); } else if (ia_valid & (ATTR_MTIME | ATTR_MTIME_SET)) { obd_flag flags; struct obd_info oinfo = { { { 0 } } }; struct obdo *oa; OBDO_ALLOC(oa); CDEBUG(D_INODE, "set mtime on OST inode %lu to %lu\n", inode->i_ino, LTIME_S(attr->ia_mtime)); if (oa) { oa->o_id = lsm->lsm_object_id; oa->o_valid = OBD_MD_FLID; flags = OBD_MD_FLTYPE | OBD_MD_FLATIME | OBD_MD_FLMTIME | OBD_MD_FLCTIME | OBD_MD_FLFID | OBD_MD_FLGENER; obdo_from_inode(oa, inode, flags); oinfo.oi_oa = oa; oinfo.oi_md = lsm; rc = obd_setattr_rqset(sbi->ll_osc_exp, &oinfo, NULL); if (rc) CERROR("obd_setattr_async fails: rc=%d\n", rc); OBDO_FREE(oa); } else { rc = -ENOMEM; } } RETURN(rc);}int ll_setattr(struct dentry *de, struct iattr *attr){ if ((attr->ia_valid & (ATTR_CTIME|ATTR_SIZE|ATTR_MODE)) == (ATTR_CTIME|ATTR_SIZE|ATTR_MODE)) attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE; return ll_setattr_raw(de->d_inode, attr);}int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs, __u64 max_age, __u32 flags){ struct ll_sb_info *sbi = ll_s2sbi(sb); struct obd_statfs obd_osfs; int rc; ENTRY; rc = obd_statfs(class_exp2obd(sbi->ll_mdc_exp), osfs, max_age, flags); if (rc) { CERROR("mdc_statfs fails: rc = %d\n", rc); RETURN(rc); } osfs->os_type = sb->s_magic; CDEBUG(D_SUPER, "MDC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n", osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files); rc = obd_statfs_rqset(class_exp2obd(sbi->ll_osc_exp), &obd_osfs, max_age, flags); if (rc) { CERROR("obd_statfs fails: rc = %d\n", rc); RETURN(rc); } CDEBUG(D_SUPER, "OSC blocks "LPU64"/"LPU64" objects "LPU64"/"LPU64"\n", obd_osfs.os_bavail, obd_osfs.os_blocks, obd_osfs.os_ffree, obd_osfs.os_files); osfs->os_bsize = obd_osfs.os_bsize; osfs->os_blocks = obd_osfs.os_blocks; osfs->os_bfree = obd_osfs.os_bfree; osfs->os_bavail = obd_osfs.os_bavail; /* If we don't have as many objects free on the OST as inodes * on the MDS, we reduce the total number of inodes to * compensate, so that the "inodes in use" number is correct. */ if (obd_osfs.os_ffree < osfs->os_ffree) { osfs->os_files = (osfs->os_files - osfs->os_ffree) + obd_osfs.os_ffree; osfs->os_ffree = obd_osfs.os_ffree; } RETURN(rc);}#ifndef HAVE_STATFS_DENTRY_PARAMint ll_statfs(struct super_block *sb, struct kstatfs *sfs){#elseint ll_statfs(struct dentry *de, struct kstatfs *sfs){ struct super_block *sb = de->d_sb;#endif struct obd_statfs osfs; int rc; CDEBUG(D_VFSTRACE, "VFS Op: at "LPU64" jiffies\n", get_jiffies_64()); ll_stats_ops_tally(ll_s2sbi(sb), LPROC_LL_STAFS, 1); /* For now we will always get up-to-date statfs values, but in the * future we may allow some amount of caching on the client (e.g. * from QOS or lprocfs updates). */ rc = ll_statfs_internal(sb, &osfs, cfs_time_current_64() - 1, 0); if (rc) return rc; statfs_unpack(sfs, &osfs); /* We need to downshift for all 32-bit kernels, because we can't * tell if the kernel is being called via sys_statfs64() or not. * Stop before overflowing f_bsize - in which case it is better * to just risk EOVERFLOW if caller is using old sys_statfs(). */ if (sizeof(long) < 8) { while (osfs.os_blocks > ~0UL && sfs->f_bsize < 0x40000000) { sfs->f_bsize <<= 1; osfs.os_blocks >>= 1; osfs.os_bfree >>= 1; osfs.os_bavail >>= 1; } } sfs->f_blocks = osfs.os_blocks; sfs->f_bfree = osfs.os_bfree; sfs->f_bavail = osfs.os_bavail; return 0;}void ll_inode_size_lock(struct inode *inode, int lock_lsm){ struct ll_inode_info *lli; struct lov_stripe_md *lsm; lli = ll_i2info(inode); LASSERT(lli->lli_size_sem_owner != current); down(&lli->lli_size_sem); LASSERT(lli->lli_size_sem_owner == NULL); lli->lli_size_sem_owner = current; lsm = lli->lli_smd; LASSERTF(lsm != NULL || lock_lsm == 0, "lsm %p, lock_lsm %d\n", lsm, lock_lsm); if (lock_lsm) lov_stripe_lock(lsm);}void ll_inode_size_unlock(struct inode *inode, int unlock_lsm){ struct ll_inode_info *lli; struct lov_stripe_md *lsm; lli = ll_i2info(inode); lsm = lli->lli_smd; LASSERTF(lsm != NULL || unlock_lsm == 0, "lsm %p, lock_lsm %d\n", lsm, unlock_lsm); if (unlock_lsm) lov_stripe_unlock(lsm); LASSERT(lli->lli_size_sem_owner == current); lli->lli_size_sem_owner = NULL; up(&lli->lli_size_sem);}static void ll_replace_lsm(struct inode *inode, struct lov_stripe_md *lsm){ struct ll_inode_info *lli = ll_i2info(inode); dump_lsm(D_INODE, lsm); dump_lsm(D_INODE, lli->lli_smd); LASSERTF(lsm->lsm_magic == LOV_MAGIC_JOIN, "lsm must be joined lsm %p\n", lsm); obd_free_memmd(ll_i2obdexp(inode), &lli->lli_smd); CDEBUG(D_INODE, "replace lsm %p to lli_smd %p for inode %lu%u(%p)\n", lsm, lli->lli_smd, inode->i_ino, inode->i_generation, inode); lli->lli_smd = lsm; lli->lli_maxbytes = lsm->lsm_maxbytes; if (lli->lli_maxbytes > PAGE_CACHE_MAXBYTES) lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;}void ll_update_inode(struct inode *inode, struct lustre_md *md){ struct ll_inode_info *lli = ll_i2info(inode); struct mds_body *body = md->body; struct lov_stripe_md *lsm = md->lsm; LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0)); if (lsm != NULL) { if (lli->lli_smd == NULL) { if (lsm->lsm_magic != LOV_MAGIC && lsm->lsm_magic != LOV_MAGIC_JOIN) { dump_lsm(D_ERROR, lsm); LBUG(); } CDEBUG(D_INODE, "adding lsm %p to inode %lu/%u(%p)\n", lsm, inode->i_ino, inode->i_generation, inode); /* ll_inode_size_lock() requires it is only called * with lli_smd != NULL or lock_lsm == 0 or we can * race between lock/unlock. bug 9547 */ lli->lli_smd = lsm; lli->lli_maxbytes = lsm->lsm_maxbytes; if (lli->lli_maxbytes > PAGE_CACHE_MAXBYTES) lli->lli_maxbytes = PAGE_CACHE_MAXBYTES; } else { if (lli->lli_smd->lsm_magic == lsm->lsm_magic && lli->lli_smd->lsm_stripe_count == lsm->lsm_stripe_count) { if (lov_stripe_md_cmp(lli->lli_smd, lsm)) { CERROR("lsm mismatch for inode %ld\n", inode->i_ino); CERROR("lli_smd:\n"); dump_lsm(D_ERROR, lli->lli_smd); CERROR("lsm:\n"); dump_lsm(D_ERROR, lsm); LBUG(); } } else ll_replace_lsm(inode, lsm); } if (lli->lli_smd != lsm) obd_free_memmd(ll_i2obdexp(inode), &lsm); }#ifdef CONFIG_FS_POSIX_ACL LASSERT(!md->posix_acl || (body->valid & OBD_MD_FLACL)); if (body->valid & OBD_MD_FLACL) { spin_lock(&lli->lli_lock); if (lli->lli_posix_acl) posix_acl_release(lli->lli_posix_acl); lli->lli_posix_acl = md->posix_acl; spin_unlock(&lli->lli_lock); }#endif if (body->valid & OBD_MD_FLID) inode->i_ino = body->ino; if (body->valid & OBD_MD_FLATIME && body->atime > LTIME_S(inode->i_atime)) LTIME_S(inode->i_atime) = body->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, so take mtime from mds for the same ctimes. */ if (body->valid & OBD_MD_FLCTIME && body->ctime >= LTIME_S(inode->i_ctime)) { LTIME_S(inode->i_ctime) = body->ctime; if (body->valid & OBD_MD_FLMTIME) { CDEBUG(D_INODE, "setting ino %lu mtime " "from %lu to "LPU64"\n", inode->i_ino, LTIME_S(inode->i_mtime), body->mtime); LTIME_S(inode->i_mtime) = body->mtime; } } if (body->valid & OBD_MD_FLMODE) inode->i_mode = (inode->i_mode & S_IFMT)|(body->mode & ~S_IFMT); if (body->valid & OBD_MD_FLTYPE) inode->i_mode = (inode->i_mode & ~S_IFMT)|(body->mode & S_IFMT); if (S_ISREG(inode->i_mode)) { inode->i_blkbits = min(PTLRPC_MAX_BRW_BITS+1, LL_MAX_BLKSIZE_BITS); } else { inode->i_blkbits = inode->i_sb->s_blocksize_bits; }#ifdef HAVE_INODE_BLKSIZE inode->i_blksize = 1<<inode->i_blkbits;#endif if (body->valid & OBD_MD_FLUID) inode->i_uid = body->uid; if (body->valid & OBD_MD_FLGID) inode->i_gid = body->gid; if (body->valid & OBD_MD_FLFLAGS) inode->i_flags = ll_ext_to_inode_flags(body->flags); if (body->valid & OBD_MD_FLNLINK) inode->i_nlink = body->nlink; if (body->valid & OBD_MD_FLGENER) inode->i_generation = body->generation; if (body->valid & OBD_MD_FLRDEV)#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) inode->i_rdev = body->rdev;#else inode->i_rdev = old_decode_dev(body->rdev);#endif if (body->valid & OBD_MD_FLSIZE) {#if 0 /* Can't block ll_test_inode->ll_update_inode, b=14326*/ ll_inode_size_lock(inode, 0); i_size_write(inode, body->size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -