X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fllite%2Fllite_lib.c;h=b4cbe5781e35aa48130ea6ea623adbce233836be;hb=65a8ff5fbe8ca014bd01150ab102d8aa43f78cff;hp=654c87455459ff397846666b1b97be8404d475e8;hpb=ae828cd3b092a38adbc86a4da320dd9d3a0fc80c;p=fs%2Flustre-release.git diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 654c874..b4cbe57 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -221,7 +221,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, data->ocd_connect_flags2 = OBD_CONNECT2_FLR | OBD_CONNECT2_LOCK_CONVERT | OBD_CONNECT2_DIR_MIGRATE | - OBD_CONNECT2_SUM_STATFS; + OBD_CONNECT2_SUM_STATFS | + OBD_CONNECT2_ARCHIVE_ID_ARRAY; #ifdef HAVE_LRU_RESIZE_SUPPORT if (sbi->ll_flags & LL_SBI_LRU_RESIZE) @@ -296,7 +297,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, * can make sure the client can be mounted as long as MDT0 is * avaible */ err = obd_statfs(NULL, sbi->ll_md_exp, osfs, - ktime_get_seconds() -OBD_STATFS_CACHE_SECONDS, + ktime_get_seconds() - OBD_STATFS_CACHE_SECONDS, OBD_STATFS_FOR_MDT0); if (err) GOTO(out_md_fid, err); @@ -431,8 +432,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, /* OBD_CONNECT_CKSUM should always be set, even if checksums are * disabled by default, because it can still be enabled on the - * fly via /proc. As a consequence, we still need to come to an - * agreement on the supported algorithms at connect time */ + * fly via /sys. As a consequence, we still need to come to an + * agreement on the supported algorithms at connect time + */ data->ocd_connect_flags |= OBD_CONNECT_CKSUM; if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CKSUM_ADLER_ONLY)) @@ -1014,7 +1016,8 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) char *profilenm = get_profile_name(sb); struct config_llog_instance *cfg; /* %p for void* in printf needs 16+2 characters: 0xffffffffffffffff */ - const int instlen = sizeof(cfg->cfg_instance) * 2 + 2; + const int instlen = 16 + 2; + unsigned long cfg_instance = ll_get_cfg_instance(sb); char name[MAX_STRING_SIZE]; int md_len = 0; int dt_len = 0; @@ -1023,40 +1026,42 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) int err; ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb); + /* for ASLR, to map between cfg_instance and hashed ptr */ + CDEBUG(D_VFSTRACE, "VFS Op: cfg_instance %s-%016lx (sb %p)\n", + profilenm, cfg_instance, sb); try_module_get(THIS_MODULE); OBD_ALLOC_PTR(cfg); if (cfg == NULL) - GOTO(out_free, err = -ENOMEM); + GOTO(out_free_cfg, err = -ENOMEM); /* client additional sb info */ lsi->lsi_llsbi = sbi = ll_init_sbi(); if (!sbi) - GOTO(out_free, err = -ENOMEM); + GOTO(out_free_cfg, err = -ENOMEM); err = ll_options(lsi->lsi_lmd->lmd_opts, sbi); if (err) - GOTO(out_free, err); + GOTO(out_free_cfg, err); - err = super_setup_bdi_name(sb, "lustre-%p", sb); + err = super_setup_bdi_name(sb, "lustre-%016lx", cfg_instance); if (err) - GOTO(out_free, err); + GOTO(out_free_cfg, err); #ifndef HAVE_DCACHE_LOCK /* kernel >= 2.6.38 store dentry operations in sb->s_d_op. */ sb->s_d_op = &ll_d_ops; #endif /* Get fsname */ - len = strlen(lsi->lsi_lmd->lmd_profile); - ptr = strrchr(lsi->lsi_lmd->lmd_profile, '-'); + len = strlen(profilenm); + ptr = strrchr(profilenm, '-'); if (ptr && (strcmp(ptr, "-client") == 0)) len -= 7; /* Mount info */ - snprintf(name, MAX_STRING_SIZE, "%.*s-%p", len, - lsi->lsi_lmd->lmd_profile, sb); + snprintf(name, MAX_STRING_SIZE, "%.*s-%016lx", len, + profilenm, cfg_instance); /* Call ll_debugfs_register_super() before lustre_process_log() * so that "llite.*.*" params can be processed correctly. @@ -1068,17 +1073,17 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) err = 0; } - /* Generate a string unique to this super, in case some joker tries - to mount the same fs at two mount points. - Use the address of the super itself.*/ - cfg->cfg_instance = sb; + /* The cfg_instance is a value unique to this super, in case some + * joker tries to mount the same fs at two mount points. + */ + cfg->cfg_instance = cfg_instance; cfg->cfg_uuid = lsi->lsi_llsbi->ll_sb_uuid; cfg->cfg_callback = class_config_llog_handler; cfg->cfg_sub_clds = CONFIG_SUB_CLIENT; /* set up client obds */ err = lustre_process_log(sb, profilenm, cfg); if (err < 0) - GOTO(out_proc, err); + GOTO(out_debugfs, err); /* Profile set with LCFG_MOUNTOPT so we can find our mdc and osc obds */ lprof = class_get_profile(profilenm); @@ -1086,7 +1091,7 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) LCONSOLE_ERROR_MSG(0x156, "The client profile '%s' could not be" " read from the MGS. Does that filesystem " "exist?\n", profilenm); - GOTO(out_proc, err = -EINVAL); + GOTO(out_debugfs, err = -EINVAL); } CDEBUG(D_CONFIG, "Found profile %s: mdc=%s osc=%s\n", profilenm, lprof->lp_md, lprof->lp_dt); @@ -1094,34 +1099,38 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) dt_len = strlen(lprof->lp_dt) + instlen + 2; OBD_ALLOC(dt, dt_len); if (!dt) - GOTO(out_proc, err = -ENOMEM); - snprintf(dt, dt_len - 1, "%s-%p", lprof->lp_dt, cfg->cfg_instance); + GOTO(out_profile, err = -ENOMEM); + snprintf(dt, dt_len - 1, "%s-%016lx", lprof->lp_dt, cfg_instance); md_len = strlen(lprof->lp_md) + instlen + 2; OBD_ALLOC(md, md_len); if (!md) - GOTO(out_proc, err = -ENOMEM); - snprintf(md, md_len - 1, "%s-%p", lprof->lp_md, cfg->cfg_instance); + GOTO(out_free_dt, err = -ENOMEM); + snprintf(md, md_len - 1, "%s-%016lx", lprof->lp_md, cfg_instance); /* connections, registrations, sb setup */ err = client_common_fill_super(sb, md, dt, mnt); if (err < 0) - GOTO(out_proc, err); + GOTO(out_free_md, err); sbi->ll_client_common_fill_super_succeeded = 1; -out_proc: - if (err < 0) - ll_debugfs_unregister_super(sb); -out_free: +out_free_md: if (md) OBD_FREE(md, md_len); +out_free_dt: if (dt) OBD_FREE(dt, dt_len); - if (lprof != NULL) +out_profile: + if (lprof) class_put_profile(lprof); +out_debugfs: + if (err < 0) + ll_debugfs_unregister_super(sb); +out_free_cfg: if (cfg) OBD_FREE_PTR(cfg); + if (err) ll_put_super(sb); else if (sbi->ll_flags & LL_SBI_VERBOSE) @@ -1132,23 +1141,26 @@ out_free: void ll_put_super(struct super_block *sb) { struct config_llog_instance cfg, params_cfg; - struct obd_device *obd; - struct lustre_sb_info *lsi = s2lsi(sb); - struct ll_sb_info *sbi = ll_s2sbi(sb); - char *profilenm = get_profile_name(sb); + struct obd_device *obd; + struct lustre_sb_info *lsi = s2lsi(sb); + struct ll_sb_info *sbi = ll_s2sbi(sb); + char *profilenm = get_profile_name(sb); + unsigned long cfg_instance = ll_get_cfg_instance(sb); long ccc_count; int next, force = 1, rc = 0; - ENTRY; + ENTRY; if (!sbi) GOTO(out_no_sbi, 0); - CDEBUG(D_VFSTRACE, "VFS Op: sb %p - %s\n", sb, profilenm); + /* Should replace instance_id with something better for ASLR */ + CDEBUG(D_VFSTRACE, "VFS Op: cfg_instance %s-%016lx (sb %p)\n", + profilenm, cfg_instance, sb); - cfg.cfg_instance = sb; - lustre_end_log(sb, profilenm, &cfg); + cfg.cfg_instance = cfg_instance; + lustre_end_log(sb, profilenm, &cfg); - params_cfg.cfg_instance = sb; + params_cfg.cfg_instance = cfg_instance; lustre_end_log(sb, PARAMS_FILENAME, ¶ms_cfg); if (sbi->ll_md_exp) { @@ -1169,7 +1181,6 @@ void ll_put_super(struct super_block *sb) if (force == 0 && rc != -EINTR) LASSERTF(ccc_count == 0, "count: %li\n", ccc_count); - /* We need to set force before the lov_disconnect in lustre_common_put_super, since l_d cleans up osc's as well. */ if (force) { @@ -1279,9 +1290,9 @@ static struct inode *ll_iget_anon_dir(struct super_block *sb, LASSERTF(S_ISDIR(inode->i_mode), "Not slave inode "DFID"\n", PFID(fid)); - LTIME_S(inode->i_mtime) = 0; - LTIME_S(inode->i_atime) = 0; - LTIME_S(inode->i_ctime) = 0; + inode->i_mtime.tv_sec = 0; + inode->i_atime.tv_sec = 0; + inode->i_ctime.tv_sec = 0; inode->i_rdev = 0; #ifdef HAVE_BACKING_DEV_INFO @@ -1640,9 +1651,9 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, } if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME)) - CDEBUG(D_INODE, "setting mtime %lu, ctime %lu, now = %llu\n", - LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime), - (s64)ktime_get_real_seconds()); + CDEBUG(D_INODE, "setting mtime %lld, ctime %lld, now = %lld\n", + (s64)attr->ia_mtime.tv_sec, (s64)attr->ia_ctime.tv_sec, + ktime_get_real_seconds()); if (S_ISREG(inode->i_mode)) { if (attr->ia_valid & ATTR_SIZE) @@ -1935,24 +1946,25 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md) inode->i_generation = cl_fid_build_gen(&body->mbo_fid1); if (body->mbo_valid & OBD_MD_FLATIME) { - if (body->mbo_atime > LTIME_S(inode->i_atime)) - LTIME_S(inode->i_atime) = body->mbo_atime; + if (body->mbo_atime > inode->i_atime.tv_sec) + inode->i_atime.tv_sec = body->mbo_atime; lli->lli_atime = body->mbo_atime; } if (body->mbo_valid & OBD_MD_FLMTIME) { - if (body->mbo_mtime > LTIME_S(inode->i_mtime)) { - CDEBUG(D_INODE, "setting ino %lu mtime from %lu " - "to %llu\n", inode->i_ino, - LTIME_S(inode->i_mtime), body->mbo_mtime); - LTIME_S(inode->i_mtime) = body->mbo_mtime; + if (body->mbo_mtime > inode->i_mtime.tv_sec) { + CDEBUG(D_INODE, + "setting ino %lu mtime from %lld to %llu\n", + inode->i_ino, (s64)inode->i_mtime.tv_sec, + body->mbo_mtime); + inode->i_mtime.tv_sec = body->mbo_mtime; } lli->lli_mtime = body->mbo_mtime; } if (body->mbo_valid & OBD_MD_FLCTIME) { - if (body->mbo_ctime > LTIME_S(inode->i_ctime)) - LTIME_S(inode->i_ctime) = body->mbo_ctime; + if (body->mbo_ctime > inode->i_ctime.tv_sec) + inode->i_ctime.tv_sec = body->mbo_ctime; lli->lli_ctime = body->mbo_ctime; } @@ -2038,11 +2050,12 @@ int ll_read_inode2(struct inode *inode, void *opaque) /* Core attributes from the MDS first. This is a new inode, and * the VFS doesn't zero times in the core inode so we have to do * it ourselves. They will be overwritten by either MDS or OST - * attributes - we just need to make sure they aren't newer. */ - LTIME_S(inode->i_mtime) = 0; - LTIME_S(inode->i_atime) = 0; - LTIME_S(inode->i_ctime) = 0; - inode->i_rdev = 0; + * attributes - we just need to make sure they aren't newer. + */ + inode->i_mtime.tv_sec = 0; + inode->i_atime.tv_sec = 0; + inode->i_ctime.tv_sec = 0; + inode->i_rdev = 0; rc = ll_update_inode(inode, md); if (rc != 0) RETURN(rc); @@ -2081,6 +2094,8 @@ int ll_read_inode2(struct inode *inode, void *opaque) void ll_delete_inode(struct inode *inode) { struct ll_inode_info *lli = ll_i2info(inode); + struct address_space *mapping = &inode->i_data; + unsigned long nrpages; ENTRY; if (S_ISREG(inode->i_mode) && lli->lli_clob != NULL) @@ -2088,11 +2103,26 @@ void ll_delete_inode(struct inode *inode) * otherwise we may lose data while umount */ cl_sync_file_range(inode, 0, OBD_OBJECT_EOF, CL_FSYNC_LOCAL, 1); - truncate_inode_pages_final(&inode->i_data); + truncate_inode_pages_final(mapping); - LASSERTF(inode->i_data.nrpages == 0, "inode="DFID"(%p) nrpages=%lu, " + /* Workaround for LU-118: Note nrpages may not be totally updated when + * truncate_inode_pages() returns, as there can be a page in the process + * of deletion (inside __delete_from_page_cache()) in the specified + * range. Thus mapping->nrpages can be non-zero when this function + * returns even after truncation of the whole mapping. Only do this if + * npages isn't already zero. + */ + nrpages = mapping->nrpages; + if (nrpages) { + spin_lock_irq(&mapping->tree_lock); + nrpages = mapping->nrpages; + spin_unlock_irq(&mapping->tree_lock); + } /* Workaround end */ + + LASSERTF(nrpages == 0, "%s: inode="DFID"(%p) nrpages=%lu, " "see https://jira.whamcloud.com/browse/LU-118\n", - PFID(ll_inode2fid(inode)), inode, inode->i_data.nrpages); + ll_get_fsname(inode->i_sb, NULL, 0), + PFID(ll_inode2fid(inode)), inode, nrpages); #ifdef HAVE_SBOPS_EVICT_INODE ll_clear_inode(inode);