📄 llite_lib.c
字号:
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Lustre Light Super operations * * Copyright (c) 2002-2005 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 <linux/module.h>#include <linux/types.h>#include <linux/random.h>#include <linux/version.h>#include <lustre_lite.h>#include <lustre_ha.h>#include <lustre_dlm.h>#include <lprocfs_status.h>#include <lustre_disk.h>#include <lustre_param.h>#include <lustre_cache.h>#include "llite_internal.h"cfs_mem_cache_t *ll_file_data_slab;LIST_HEAD(ll_super_blocks);spinlock_t ll_sb_lock = SPIN_LOCK_UNLOCKED;extern struct address_space_operations ll_aops;extern struct address_space_operations ll_dir_aops;#ifndef log2#define log2(n) ffz(~(n))#endifstatic struct ll_sb_info *ll_init_sbi(void){ struct ll_sb_info *sbi = NULL; class_uuid_t uuid; int i; ENTRY; OBD_ALLOC(sbi, sizeof(*sbi)); if (!sbi) RETURN(NULL); spin_lock_init(&sbi->ll_lock); spin_lock_init(&sbi->ll_lco.lco_lock); spin_lock_init(&sbi->ll_pp_extent_lock); spin_lock_init(&sbi->ll_process_lock); sbi->ll_rw_stats_on = 0; INIT_LIST_HEAD(&sbi->ll_pglist); if (num_physpages >> (20 - CFS_PAGE_SHIFT) < 512) sbi->ll_async_page_max = num_physpages / 2; else sbi->ll_async_page_max = (num_physpages / 4) * 3; sbi->ll_ra_info.ra_max_pages = min(num_physpages / 8, SBI_DEFAULT_READAHEAD_MAX); sbi->ll_ra_info.ra_max_read_ahead_whole_pages = SBI_DEFAULT_READAHEAD_WHOLE_MAX; sbi->ll_contention_time = SBI_DEFAULT_CONTENTION_SECONDS; INIT_LIST_HEAD(&sbi->ll_conn_chain); INIT_LIST_HEAD(&sbi->ll_orphan_dentry_list); ll_generate_random_uuid(uuid); class_uuid_unparse(uuid, &sbi->ll_sb_uuid); CDEBUG(D_CONFIG, "generated uuid: %s\n", sbi->ll_sb_uuid.uuid); spin_lock(&ll_sb_lock); list_add_tail(&sbi->ll_list, &ll_super_blocks); spin_unlock(&ll_sb_lock);#ifdef ENABLE_CHECKSUM sbi->ll_flags |= LL_SBI_DATA_CHECKSUM;#endif#ifdef ENABLE_LLITE_CHECKSUM sbi->ll_flags |= LL_SBI_LLITE_CHECKSUM;#endif#ifdef HAVE_LRU_RESIZE_SUPPORT sbi->ll_flags |= LL_SBI_LRU_RESIZE;#endif#ifdef HAVE_EXPORT___IGET INIT_LIST_HEAD(&sbi->ll_deathrow); spin_lock_init(&sbi->ll_deathrow_lock);#endif for (i = 0; i <= LL_PROCESS_HIST_MAX; i++) { spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i].pp_r_hist.oh_lock); spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i].pp_w_hist.oh_lock); } /* metadata statahead is enabled by default */ sbi->ll_sa_max = LL_SA_RPC_DEF; RETURN(sbi);}void ll_free_sbi(struct super_block *sb){ struct ll_sb_info *sbi = ll_s2sbi(sb); ENTRY; if (sbi != NULL) { spin_lock(&ll_sb_lock); list_del(&sbi->ll_list); spin_unlock(&ll_sb_lock); OBD_FREE(sbi, sizeof(*sbi)); } EXIT;}static struct dentry_operations ll_d_root_ops = {#ifdef DCACHE_LUSTRE_INVALID .d_compare = ll_dcompare,#endif};static int client_common_fill_super(struct super_block *sb, char *mdc, char *osc){ struct inode *root = 0; struct ll_sb_info *sbi = ll_s2sbi(sb); struct obd_device *obd; struct ll_fid rootfid; struct obd_statfs osfs; struct ptlrpc_request *request = NULL; struct lustre_handle osc_conn = {0, }; struct lustre_handle mdc_conn = {0, }; struct lustre_md md; struct obd_connect_data *data = NULL; int err, checksum; ENTRY; obd = class_name2obd(mdc); if (!obd) { CERROR("MDC %s: not setup or attached\n", mdc); RETURN(-EINVAL); } OBD_ALLOC(data, sizeof(*data)); if (data == NULL) RETURN(-ENOMEM); if (proc_lustre_fs_root) { err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb, osc, mdc); if (err < 0) CERROR("could not register mount in /proc/lustre"); } /* indicate the features supported by this client */ data->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_IBITS | OBD_CONNECT_JOIN | OBD_CONNECT_ATTRFID | OBD_CONNECT_NODEVOH | OBD_CONNECT_CANCELSET | OBD_CONNECT_AT;#ifdef HAVE_LRU_RESIZE_SUPPORT if (sbi->ll_flags & LL_SBI_LRU_RESIZE) data->ocd_connect_flags |= OBD_CONNECT_LRU_RESIZE;#endif#ifdef CONFIG_FS_POSIX_ACL data->ocd_connect_flags |= OBD_CONNECT_ACL;#endif data->ocd_ibits_known = MDS_INODELOCK_FULL; data->ocd_version = LUSTRE_VERSION_CODE; if (sb->s_flags & MS_RDONLY) data->ocd_connect_flags |= OBD_CONNECT_RDONLY; if (sbi->ll_flags & LL_SBI_USER_XATTR) data->ocd_connect_flags |= OBD_CONNECT_XATTR;#ifdef HAVE_MS_FLOCK_LOCK /* force vfs to use lustre handler for flock() calls - bug 10743 */ sb->s_flags |= MS_FLOCK_LOCK;#endif if (sbi->ll_flags & LL_SBI_FLOCK) sbi->ll_fop = &ll_file_operations_flock; else if (sbi->ll_flags & LL_SBI_LOCALFLOCK) sbi->ll_fop = &ll_file_operations; else sbi->ll_fop = &ll_file_operations_noflock; err = obd_connect(&mdc_conn, obd, &sbi->ll_sb_uuid, data, NULL); if (err == -EBUSY) { LCONSOLE_ERROR_MSG(0x14f, "An MDT (mdc %s) is performing " "recovery, of which this client is not a " "part. Please wait for recovery to complete," " abort, or time out.\n", mdc); GOTO(out, err); } else if (err) { CERROR("cannot connect to %s: rc = %d\n", mdc, err); GOTO(out, err); } sbi->ll_mdc_exp = class_conn2export(&mdc_conn); err = obd_statfs(obd, &osfs, cfs_time_current_64() - HZ, 0); if (err) GOTO(out_mdc, err); /* MDC connect is surely finished by now because we actually sent * a statfs RPC, otherwise obd_connect() is asynchronous. */ *data = class_exp2cliimp(sbi->ll_mdc_exp)->imp_connect_data; LASSERT(osfs.os_bsize); sb->s_blocksize = osfs.os_bsize; sb->s_blocksize_bits = log2(osfs.os_bsize); sb->s_magic = LL_SUPER_MAGIC; /* for bug 11559. in $LINUX/fs/read_write.c, function do_sendfile(): * retval = in_file->f_op->sendfile(...); * if (*ppos > max) * retval = -EOVERFLOW; * * it will check if *ppos is greater than max. However, max equals to * s_maxbytes, which is a negative integer in a x86_64 box since loff_t * has been defined as a signed long long ineger in linux kernel. */#if BITS_PER_LONG == 64 sb->s_maxbytes = PAGE_CACHE_MAXBYTES >> 1;#else sb->s_maxbytes = PAGE_CACHE_MAXBYTES;#endif sbi->ll_namelen = osfs.os_namelen; sbi->ll_max_rw_chunk = LL_DEFAULT_MAX_RW_CHUNK; if ((sbi->ll_flags & LL_SBI_USER_XATTR) && !(data->ocd_connect_flags & OBD_CONNECT_XATTR)) { LCONSOLE_INFO("Disabling user_xattr feature because " "it is not supported on the server\n"); sbi->ll_flags &= ~LL_SBI_USER_XATTR; } if (data->ocd_connect_flags & OBD_CONNECT_ACL) {#ifdef MS_POSIXACL sb->s_flags |= MS_POSIXACL;#endif sbi->ll_flags |= LL_SBI_ACL; } else sbi->ll_flags &= ~LL_SBI_ACL; if (data->ocd_connect_flags & OBD_CONNECT_JOIN) sbi->ll_flags |= LL_SBI_JOIN; sbi->ll_sdev_orig = sb->s_dev; /* We set sb->s_dev equal on all lustre clients in order to support * NFS export clustering. NFSD requires that the FSID be the same * on all clients. */ /* s_dev is also used in lt_compare() to compare two fs, but that is * only a node-local comparison. */ sb->s_dev = get_uuid2int(sbi2mdc(sbi)->cl_target_uuid.uuid, strlen(sbi2mdc(sbi)->cl_target_uuid.uuid)); obd = class_name2obd(osc); if (!obd) { CERROR("OSC %s: not setup or attached\n", osc); GOTO(out_mdc, err = -ENODEV); } data->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_GRANT | OBD_CONNECT_REQPORTAL | OBD_CONNECT_BRW_SIZE | OBD_CONNECT_SRVLOCK | OBD_CONNECT_CANCELSET | OBD_CONNECT_AT; if (!OBD_FAIL_CHECK(OBD_FAIL_OSC_CONNECT_CKSUM)) { /* 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 */ data->ocd_connect_flags |= OBD_CONNECT_CKSUM; if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CKSUM_ADLER_ONLY)) data->ocd_cksum_types = OBD_CKSUM_ADLER; else /* send the list of supported checksum types */ data->ocd_cksum_types = OBD_CKSUM_ALL; }#ifdef HAVE_LRU_RESIZE_SUPPORT if (sbi->ll_flags & LL_SBI_LRU_RESIZE) data->ocd_connect_flags |= OBD_CONNECT_LRU_RESIZE;#endif CDEBUG(D_RPCTRACE, "ocd_connect_flags: "LPX64" ocd_version: %d " "ocd_grant: %d\n", data->ocd_connect_flags, data->ocd_version, data->ocd_grant); obd->obd_upcall.onu_owner = &sbi->ll_lco; obd->obd_upcall.onu_upcall = ll_ocd_update; data->ocd_brw_size = PTLRPC_MAX_BRW_PAGES << CFS_PAGE_SHIFT; err = obd_connect(&osc_conn, obd, &sbi->ll_sb_uuid, data, NULL); if (err == -EBUSY) { LCONSOLE_ERROR_MSG(0x150, "An OST (osc %s) is performing " "recovery, of which this client is not a " "part. Please wait for recovery to " "complete, abort, or time out.\n", osc); GOTO(out, err); } else if (err) { CERROR("cannot connect to %s: rc = %d\n", osc, err); GOTO(out_mdc, err); } sbi->ll_osc_exp = class_conn2export(&osc_conn); spin_lock(&sbi->ll_lco.lco_lock); sbi->ll_lco.lco_flags = data->ocd_connect_flags; spin_unlock(&sbi->ll_lco.lco_lock); err = obd_register_page_removal_cb(sbi->ll_osc_exp, ll_page_removal_cb, ll_pin_extent_cb); if (err) { CERROR("cannot register page removal callback: rc = %d\n",err); GOTO(out_osc, err); } err = obd_register_lock_cancel_cb(sbi->ll_osc_exp, ll_extent_lock_cancel_cb); if (err) { CERROR("cannot register lock cancel callback: rc = %d\n", err); GOTO(out_page_rm_cb, err); } err = mdc_init_ea_size(sbi->ll_mdc_exp, sbi->ll_osc_exp); if (err) { CERROR("cannot set max EA and cookie sizes: rc = %d\n", err); GOTO(out_lock_cn_cb, err); } err = obd_prep_async_page(sbi->ll_osc_exp, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0, NULL); if (err < 0) { LCONSOLE_ERROR_MSG(0x151, "There are no OST's in this " "filesystem. There must be at least one " "active OST for a client to start.\n"); GOTO(out_lock_cn_cb, err); } if (!ll_async_page_slab) { ll_async_page_slab_size = size_round(sizeof(struct ll_async_page)) + err; ll_async_page_slab = cfs_mem_cache_create("ll_async_page", ll_async_page_slab_size, 0, 0); if (!ll_async_page_slab) GOTO(out_lock_cn_cb, -ENOMEM); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -