Whamcloud - gitweb
LU-1201 checksum: add libcfs crypto hash
[fs/lustre-release.git] / lustre / llite / llite_lib.c
index 41131a9..8c64fba 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -89,7 +87,7 @@ static struct ll_sb_info *ll_init_sbi(void)
                 RETURN(NULL);
 
         cfs_spin_lock_init(&sbi->ll_lock);
-        cfs_init_mutex(&sbi->ll_lco.lco_lock);
+        cfs_mutex_init(&sbi->ll_lco.lco_lock);
         cfs_spin_lock_init(&sbi->ll_pp_extent_lock);
         cfs_spin_lock_init(&sbi->ll_process_lock);
         sbi->ll_rw_stats_on = 0;
@@ -122,6 +120,7 @@ static struct ll_sb_info *ll_init_sbi(void)
         cfs_list_add_tail(&sbi->ll_list, &ll_super_blocks);
         cfs_spin_unlock(&ll_sb_lock);
 
+        sbi->ll_flags |= LL_SBI_VERBOSE;
 #ifdef ENABLE_CHECKSUM
         sbi->ll_flags |= LL_SBI_CHECKSUM;
 #endif
@@ -214,7 +213,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                                   OBD_CONNECT_CANCELSET | OBD_CONNECT_FID     |
                                   OBD_CONNECT_AT       | OBD_CONNECT_LOV_V3   |
                                   OBD_CONNECT_RMT_CLIENT | OBD_CONNECT_VBR    |
-                                  OBD_CONNECT_FULL20   | OBD_CONNECT_64BITHASH;
+                                  OBD_CONNECT_FULL20   | OBD_CONNECT_64BITHASH|
+                                 OBD_CONNECT_EINPROGRESS |
+                                 OBD_CONNECT_JOBSTATS;
 
         if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
                 data->ocd_connect_flags |= OBD_CONNECT_SOM;
@@ -275,7 +276,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                 GOTO(out_md, err);
         }
 
-        err = obd_statfs(obd, osfs,
+        err = obd_statfs(NULL, sbi->ll_md_exp, osfs,
                          cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), 0);
         if (err)
                 GOTO(out_md_fid, err);
@@ -305,7 +306,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
         }
 
         size = sizeof(*data);
-        err = obd_get_info(sbi->ll_md_exp, sizeof(KEY_CONN_DATA),
+        err = obd_get_info(NULL, sbi->ll_md_exp, sizeof(KEY_CONN_DATA),
                            KEY_CONN_DATA,  &size, data, NULL);
         if (err) {
                 CERROR("Get connect data failed: %d \n", err);
@@ -316,20 +317,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
         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 integer in linux kernel. */
-#if BITS_PER_LONG == 64
-        sb->s_maxbytes = PAGE_CACHE_MAXBYTES >> 1;
-#else
-        sb->s_maxbytes = PAGE_CACHE_MAXBYTES;
-#endif
+        sb->s_maxbytes = MAX_LFS_FILESIZE;
         sbi->ll_namelen = osfs->os_namelen;
         sbi->ll_max_rw_chunk = LL_DEFAULT_MAX_RW_CHUNK;
 
@@ -397,7 +385,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                                   OBD_CONNECT_AT | OBD_CONNECT_RMT_CLIENT |
                                   OBD_CONNECT_OSS_CAPA | OBD_CONNECT_VBR|
                                   OBD_CONNECT_FULL20 | OBD_CONNECT_64BITHASH |
-                                  OBD_CONNECT_MAXBYTES;
+                                  OBD_CONNECT_MAXBYTES |
+                                 OBD_CONNECT_EINPROGRESS |
+                                 OBD_CONNECT_JOBSTATS;
 
         if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
                 data->ocd_connect_flags |= OBD_CONNECT_SOM;
@@ -409,10 +399,10 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                  * 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
-                        data->ocd_cksum_types = cksum_types_supported();
+               if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CKSUM_ADLER_ONLY))
+                       data->ocd_cksum_types = OBD_CKSUM_ADLER;
+               else
+                       data->ocd_cksum_types = cksum_types_supported_client();
         }
 
 #ifdef HAVE_LRU_RESIZE_SUPPORT
@@ -449,11 +439,11 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                 GOTO(out_dt, err);
         }
 
-        cfs_mutex_down(&sbi->ll_lco.lco_lock);
+        cfs_mutex_lock(&sbi->ll_lco.lco_lock);
         sbi->ll_lco.lco_flags = data->ocd_connect_flags;
         sbi->ll_lco.lco_md_exp = sbi->ll_md_exp;
         sbi->ll_lco.lco_dt_exp = sbi->ll_dt_exp;
-        cfs_mutex_up(&sbi->ll_lco.lco_lock);
+        cfs_mutex_unlock(&sbi->ll_lco.lco_lock);
 
         fid_zero(&sbi->ll_root_fid);
         err = md_getstatus(sbi->ll_md_exp, &sbi->ll_root_fid, &oc);
@@ -539,7 +529,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
 #endif
 
         checksum = sbi->ll_flags & LL_SBI_CHECKSUM;
-        err = obd_set_info_async(sbi->ll_dt_exp, sizeof(KEY_CHECKSUM),
+        err = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CHECKSUM),
                                  KEY_CHECKSUM, sizeof(checksum), &checksum,
                                  NULL);
         cl_sb_init(sb);
@@ -593,7 +583,7 @@ int ll_get_max_mdsize(struct ll_sb_info *sbi, int *lmmsize)
 
         *lmmsize = obd_size_diskmd(sbi->ll_dt_exp, NULL);
         size = sizeof(int);
-        rc = obd_get_info(sbi->ll_md_exp, sizeof(KEY_MAX_EASIZE),
+        rc = obd_get_info(NULL, sbi->ll_md_exp, sizeof(KEY_MAX_EASIZE),
                           KEY_MAX_EASIZE, &size, lmmsize, NULL);
         if (rc)
                 CERROR("Get max mdsize error rc %d \n", rc);
@@ -837,7 +827,16 @@ static int ll_options(char *options, int *flags)
                         *flags |= tmp;
                         goto next;
                 }
-
+                tmp = ll_set_opt("verbose", s1, LL_SBI_VERBOSE);
+                if (tmp) {
+                        *flags |= tmp;
+                        goto next;
+                }
+                tmp = ll_set_opt("noverbose", s1, LL_SBI_VERBOSE);
+                if (tmp) {
+                        *flags &= ~tmp;
+                        goto next;
+                }
                 LCONSOLE_ERROR_MSG(0x152, "Unknown option '%s', won't mount.\n",
                                    s1);
                 RETURN(-EINVAL);
@@ -857,10 +856,11 @@ void ll_lli_init(struct ll_inode_info *lli)
         lli->lli_inode_magic = LLI_INODE_MAGIC;
         lli->lli_flags = 0;
         lli->lli_ioepoch = 0;
+        lli->lli_maxbytes = MAX_LFS_FILESIZE;
         cfs_spin_lock_init(&lli->lli_lock);
         lli->lli_posix_acl = NULL;
         lli->lli_remote_perms = NULL;
-        cfs_sema_init(&lli->lli_rmtperm_sem, 1);
+        cfs_mutex_init(&lli->lli_rmtperm_mutex);
         /* Do not set lli_fid, it has been initialized already. */
         fid_zero(&lli->lli_pfid);
         CFS_INIT_LIST_HEAD(&lli->lli_close_list);
@@ -875,14 +875,14 @@ void ll_lli_init(struct ll_inode_info *lli)
         lli->lli_open_fd_read_count = 0;
         lli->lli_open_fd_write_count = 0;
         lli->lli_open_fd_exec_count = 0;
-        cfs_sema_init(&lli->lli_och_sem, 1);
+        cfs_mutex_init(&lli->lli_och_mutex);
         cfs_spin_lock_init(&lli->lli_agl_lock);
         lli->lli_smd = NULL;
         lli->lli_clob = NULL;
 
         LASSERT(lli->lli_vfs_inode.i_mode != 0);
         if (S_ISDIR(lli->lli_vfs_inode.i_mode)) {
-                cfs_sema_init(&lli->lli_readdir_sem, 1);
+                cfs_mutex_init(&lli->lli_readdir_mutex);
                 lli->lli_opendir_key = NULL;
                 lli->lli_sai = NULL;
                 lli->lli_sa_pos = 0;
@@ -893,9 +893,8 @@ void ll_lli_init(struct ll_inode_info *lli)
                 cfs_sema_init(&lli->lli_size_sem, 1);
                 lli->lli_size_sem_owner = NULL;
                 lli->lli_symlink_name = NULL;
-                lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
                 cfs_init_rwsem(&lli->lli_trunc_sem);
-                cfs_sema_init(&lli->lli_write_sem, 1);
+                cfs_mutex_init(&lli->lli_write_mutex);
                 lli->lli_async_rc = 0;
                 lli->lli_write_rc = 0;
                 cfs_init_rwsem(&lli->lli_glimpse_sem);
@@ -1010,8 +1009,8 @@ out_free:
                 OBD_FREE(dt, strlen(lprof->lp_dt) + instlen + 2);
         if (err)
                 ll_put_super(sb);
-        else
-                LCONSOLE_WARN("Client %s has started\n", profilenm);
+        else if (sbi->ll_flags & LL_SBI_VERBOSE)
+                LCONSOLE_WARN("Mounted %s\n", profilenm);
 
         OBD_FREE_PTR(cfg);
         RETURN(err);
@@ -1063,6 +1062,9 @@ void ll_put_super(struct super_block *sb)
                 class_manual_cleanup(obd);
         }
 
+        if (sbi->ll_flags & LL_SBI_VERBOSE)
+                LCONSOLE_WARN("Unmounted %s\n", profilenm ? profilenm : "");
+
         if (profilenm)
                 class_del_profile(profilenm);
 
@@ -1078,8 +1080,6 @@ void ll_put_super(struct super_block *sb)
 
         cl_env_cache_purge(~0);
 
-        LCONSOLE_WARN("client %p umount complete\n", cfg.cfg_instance);
-
         cfs_module_put(THIS_MODULE);
 
         EXIT;
@@ -1334,12 +1334,20 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
 
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu valid %x\n", inode->i_ino,
                attr->ia_valid);
-        ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETATTR, 1);
 
         if (ia_valid & ATTR_SIZE) {
+                /* Check new size against VFS/VM file size limit and rlimit */
+                rc = inode_newsize_ok(inode, attr->ia_size);
+                if (rc)
+                        RETURN(rc);
+
+                /* The maximum Lustre file size is variable, based on the
+                 * OST maximum object size and number of stripes.  This
+                 * needs another check in addition to the VFS check above. */
                 if (attr->ia_size > ll_file_maxbytes(inode)) {
-                        CDEBUG(D_INODE, "file too large %llu > "LPU64"\n",
-                               attr->ia_size, ll_file_maxbytes(inode));
+                        CDEBUG(D_INODE,"file "DFID" too large %llu > "LPU64"\n",
+                               PFID(&lli->lli_fid), attr->ia_size,
+                               ll_file_maxbytes(inode));
                         RETURN(-EFBIG);
                 }
 
@@ -1416,23 +1424,30 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
         if (ia_valid & (ATTR_SIZE |
                         ATTR_ATIME | ATTR_ATIME_SET |
                         ATTR_MTIME | ATTR_MTIME_SET))
-                /* on truncate and utimes send attributes to osts, setting
-                 * mtime/atime to past will be performed under PW 0:EOF extent
-                 * lock (new_size:EOF for truncate)
-                 * it may seem excessive to send mtime/atime updates to osts
-                 * when not setting times to past, but it is necessary due to
-                 * possible time de-synchronization */
+                /* For truncate and utimes sending attributes to OSTs, setting
+                 * mtime/atime to the past will be performed under PW [0:EOF]
+                 * extent lock (new_size:EOF for truncate).  It may seem
+                 * excessive to send mtime/atime updates to OSTs when not
+                 * setting times to past, but it is necessary due to possible
+                 * time de-synchronization between MDT inode and OST objects */
                 rc = ll_setattr_ost(inode, attr);
         EXIT;
 out:
         if (op_data) {
-                if (op_data->op_ioepoch)
+                if (op_data->op_ioepoch) {
                         rc1 = ll_setattr_done_writing(inode, op_data, mod);
+                        if (!rc)
+                                rc = rc1;
+                }
                 ll_finish_md_op_data(op_data);
         }
         if (!S_ISDIR(inode->i_mode))
                 cfs_up_write(&lli->lli_trunc_sem);
-        return rc ? rc : rc1;
+
+        ll_stats_ops_tally(ll_i2sbi(inode), (ia_valid & ATTR_SIZE) ?
+                           LPROC_LL_TRUNC : LPROC_LL_SETATTR, 1);
+
+        return rc;
 }
 
 int ll_setattr(struct dentry *de, struct iattr *attr)
@@ -1471,7 +1486,7 @@ int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
         int rc;
         ENTRY;
 
-        rc = obd_statfs(class_exp2obd(sbi->ll_md_exp), osfs, max_age, flags);
+        rc = obd_statfs(NULL, sbi->ll_md_exp, osfs, max_age, flags);
         if (rc) {
                 CERROR("md_statfs fails: rc = %d\n", rc);
                 RETURN(rc);
@@ -1485,8 +1500,7 @@ int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
         if (sbi->ll_flags & LL_SBI_LAZYSTATFS)
                 flags |= OBD_STATFS_NODELAY;
 
-        rc = obd_statfs_rqset(class_exp2obd(sbi->ll_dt_exp),
-                              &obd_osfs, max_age, flags);
+        rc = obd_statfs_rqset(sbi->ll_dt_exp, &obd_osfs, max_age, flags);
         if (rc) {
                 CERROR("obd_statfs fails: rc = %d\n", rc);
                 RETURN(rc);
@@ -1603,7 +1617,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
         if (lsm != NULL) {
                 LASSERT(S_ISREG(inode->i_mode));
 
-                cfs_down(&lli->lli_och_sem);
+                cfs_mutex_lock(&lli->lli_och_mutex);
                 if (lli->lli_smd == NULL) {
                         if (lsm->lsm_magic != LOV_MAGIC_V1 &&
                             lsm->lsm_magic != LOV_MAGIC_V3) {
@@ -1620,12 +1634,12 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
                         cfs_spin_lock(&lli->lli_lock);
                         lli->lli_smd = lsm;
                         cfs_spin_unlock(&lli->lli_lock);
-                        cfs_up(&lli->lli_och_sem);
+                        cfs_mutex_unlock(&lli->lli_och_mutex);
                         lli->lli_maxbytes = lsm->lsm_maxbytes;
-                        if (lli->lli_maxbytes > PAGE_CACHE_MAXBYTES)
-                                lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
+                        if (lli->lli_maxbytes > MAX_LFS_FILESIZE)
+                                lli->lli_maxbytes = MAX_LFS_FILESIZE;
                 } else {
-                        cfs_up(&lli->lli_och_sem);
+                        cfs_mutex_unlock(&lli->lli_och_mutex);
                         LASSERT(lli->lli_smd->lsm_magic == lsm->lsm_magic &&
                                 lli->lli_smd->lsm_stripe_count ==
                                 lsm->lsm_stripe_count);
@@ -1927,8 +1941,7 @@ int ll_iocontrol(struct inode *inode, struct file *file,
                 oinfo.oi_oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS |
                                        OBD_MD_FLGROUP;
                 oinfo.oi_capa = ll_mdscapa_get(inode);
-                obdo_from_inode(oinfo.oi_oa, inode,
-                                &ll_i2info(inode)->lli_fid, 0);
+                obdo_set_parent_fid(oinfo.oi_oa, &ll_i2info(inode)->lli_fid);
                 rc = obd_setattr_rqset(sbi->ll_dt_exp, &oinfo, NULL);
                 capa_put(oinfo.oi_capa);
                 OBDO_FREE(oinfo.oi_oa);
@@ -1956,10 +1969,10 @@ int ll_flush_ctx(struct inode *inode)
 
         CDEBUG(D_SEC, "flush context for user %d\n", cfs_curproc_uid());
 
-        obd_set_info_async(sbi->ll_md_exp,
+        obd_set_info_async(NULL, sbi->ll_md_exp,
                            sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
                            0, NULL, NULL);
-        obd_set_info_async(sbi->ll_dt_exp,
+        obd_set_info_async(NULL, sbi->ll_dt_exp,
                            sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
                            0, NULL, NULL);
         return 0;
@@ -2045,18 +2058,20 @@ void ll_umount_begin(struct super_block *sb)
 int ll_remount_fs(struct super_block *sb, int *flags, char *data)
 {
         struct ll_sb_info *sbi = ll_s2sbi(sb);
+        char *profilenm = get_profile_name(sb);
         int err;
         __u32 read_only;
 
         if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
                 read_only = *flags & MS_RDONLY;
-                err = obd_set_info_async(sbi->ll_md_exp,
+                err = obd_set_info_async(NULL, sbi->ll_md_exp,
                                          sizeof(KEY_READ_ONLY),
                                          KEY_READ_ONLY, sizeof(read_only),
                                          &read_only, NULL);
                 if (err) {
-                        CERROR("Failed to change the read-only flag during "
-                               "remount: %d\n", err);
+                        LCONSOLE_WARN("Failed to remount %s %s (%d)\n",
+                                      profilenm, read_only ?
+                                      "read-only" : "read-write", err);
                         return err;
                 }
 
@@ -2064,6 +2079,10 @@ int ll_remount_fs(struct super_block *sb, int *flags, char *data)
                         sb->s_flags |= MS_RDONLY;
                 else
                         sb->s_flags &= ~MS_RDONLY;
+
+                if (sbi->ll_flags & LL_SBI_VERBOSE)
+                        LCONSOLE_WARN("Remounted %s %s\n", profilenm,
+                                      read_only ?  "read-only" : "read-write");
         }
         return 0;
 }