Whamcloud - gitweb
LU-819 utils: Fix lfs getstripe -M
[fs/lustre-release.git] / lustre / llite / llite_lib.c
index 713d581..4e49985 100644 (file)
@@ -142,6 +142,8 @@ static struct ll_sb_info *ll_init_sbi(void)
         sbi->ll_sa_max = LL_SA_RPC_DEF;
         cfs_atomic_set(&sbi->ll_sa_total, 0);
         cfs_atomic_set(&sbi->ll_sa_wrong, 0);
+        cfs_atomic_set(&sbi->ll_agl_total, 0);
+        sbi->ll_flags |= LL_SBI_AGL_ENABLED;
 
         RETURN(sbi);
 }
@@ -854,28 +856,54 @@ next:
 void ll_lli_init(struct ll_inode_info *lli)
 {
         lli->lli_inode_magic = LLI_INODE_MAGIC;
-        cfs_sema_init(&lli->lli_size_sem, 1);
-        cfs_sema_init(&lli->lli_write_sem, 1);
-        cfs_init_rwsem(&lli->lli_trunc_sem);
         lli->lli_flags = 0;
-        lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
+        lli->lli_ioepoch = 0;
         cfs_spin_lock_init(&lli->lli_lock);
-        CFS_INIT_LIST_HEAD(&lli->lli_close_list);
-        lli->lli_inode_magic = LLI_INODE_MAGIC;
-        cfs_sema_init(&lli->lli_och_sem, 1);
-        lli->lli_mds_read_och = lli->lli_mds_write_och = NULL;
-        lli->lli_mds_exec_och = NULL;
-        lli->lli_open_fd_read_count = lli->lli_open_fd_write_count = 0;
-        lli->lli_open_fd_exec_count = 0;
-        CFS_INIT_LIST_HEAD(&lli->lli_dead_list);
+        lli->lli_posix_acl = NULL;
         lli->lli_remote_perms = NULL;
-        lli->lli_rmtperm_utime = 0;
         cfs_sema_init(&lli->lli_rmtperm_sem, 1);
+        /* Do not set lli_fid, it has been initialized already. */
+        fid_zero(&lli->lli_pfid);
+        CFS_INIT_LIST_HEAD(&lli->lli_close_list);
         CFS_INIT_LIST_HEAD(&lli->lli_oss_capas);
-        cfs_spin_lock_init(&lli->lli_sa_lock);
+        cfs_atomic_set(&lli->lli_open_count, 0);
+        lli->lli_mds_capa = NULL;
+        lli->lli_rmtperm_time = 0;
+        lli->lli_pending_och = NULL;
+        lli->lli_mds_read_och = NULL;
+        lli->lli_mds_write_och = NULL;
+        lli->lli_mds_exec_och = NULL;
+        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_spin_lock_init(&lli->lli_agl_lock);
+        lli->lli_smd = NULL;
         lli->lli_clob = NULL;
-        cfs_sema_init(&lli->lli_readdir_sem, 1);
-        fid_zero(&lli->lli_pfid);
+
+        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);
+                lli->lli_opendir_key = NULL;
+                lli->lli_sai = NULL;
+                lli->lli_sa_pos = 0;
+                lli->lli_def_acl = NULL;
+                cfs_spin_lock_init(&lli->lli_sa_lock);
+                lli->lli_opendir_pid = 0;
+        } else {
+                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);
+                lli->lli_async_rc = 0;
+                lli->lli_write_rc = 0;
+                cfs_init_rwsem(&lli->lli_glimpse_sem);
+                lli->lli_glimpse_time = 0;
+                CFS_INIT_LIST_HEAD(&lli->lli_agl_list);
+                lli->lli_agl_index = 0;
+        }
 }
 
 static inline int ll_bdi_register(struct backing_dev_info *bdi)
@@ -1103,8 +1131,8 @@ void ll_clear_inode(struct inode *inode)
 
         if (S_ISDIR(inode->i_mode)) {
                 /* these should have been cleared in ll_file_release */
-                LASSERT(lli->lli_sai == NULL);
                 LASSERT(lli->lli_opendir_key == NULL);
+                LASSERT(lli->lli_sai == NULL);
                 LASSERT(lli->lli_opendir_pid == 0);
         }
 
@@ -1123,7 +1151,7 @@ void ll_clear_inode(struct inode *inode)
         if (lli->lli_mds_read_och)
                 ll_md_real_close(inode, FMODE_READ);
 
-        if (lli->lli_symlink_name) {
+        if (S_ISLNK(inode->i_mode) && lli->lli_symlink_name) {
                 OBD_FREE(lli->lli_symlink_name,
                          strlen(lli->lli_symlink_name) + 1);
                 lli->lli_symlink_name = NULL;
@@ -1147,6 +1175,9 @@ void ll_clear_inode(struct inode *inode)
         lli->lli_inode_magic = LLI_INODE_DEAD;
 
         ll_clear_inode_capas(inode);
+        if (!S_ISDIR(inode->i_mode))
+                LASSERT(cfs_list_empty(&lli->lli_agl_list));
+
         /*
          * XXX This has to be done before lsm is freed below, because
          * cl_object still uses inode lsm.
@@ -1162,10 +1193,11 @@ void ll_clear_inode(struct inode *inode)
         EXIT;
 }
 
-int ll_md_setattr(struct inode *inode, struct md_op_data *op_data,
+int ll_md_setattr(struct dentry *dentry, struct md_op_data *op_data,
                   struct md_open_data **mod)
 {
         struct lustre_md md;
+        struct inode *inode = dentry->d_inode;
         struct ll_sb_info *sbi = ll_i2sbi(inode);
         struct ptlrpc_request *request = NULL;
         int rc;
@@ -1186,7 +1218,7 @@ int ll_md_setattr(struct inode *inode, struct md_op_data *op_data,
                          * Pretend we done everything. */
                         if (!S_ISREG(inode->i_mode) &&
                             !S_ISDIR(inode->i_mode))
-                                rc = inode_setattr(inode, &op_data->op_attr);
+                                rc = simple_setattr(dentry, &op_data->op_attr);
                 } else if (rc != -EPERM && rc != -EACCES && rc != -ETXTBSY) {
                         CERROR("md_setattr fails: rc = %d\n", rc);
                 }
@@ -1205,7 +1237,7 @@ int ll_md_setattr(struct inode *inode, struct md_op_data *op_data,
          * 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, &op_data->op_attr);
+        rc = simple_setattr(dentry, &op_data->op_attr);
 
         /* Extract epoch data if obtained. */
         op_data->op_handle = md.body->handle;
@@ -1282,8 +1314,9 @@ static int ll_setattr_ost(struct inode *inode, struct iattr *attr)
  * I don't believe it is possible to get e.g. ATTR_MTIME_SET and ATTR_SIZE
  * at the same time.
  */
-int ll_setattr_raw(struct inode *inode, struct iattr *attr)
+int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
 {
+        struct inode *inode = dentry->d_inode;
         struct ll_inode_info *lli = ll_i2info(inode);
         struct lov_stripe_md *lsm = lli->lli_smd;
         struct md_op_data *op_data = NULL;
@@ -1347,7 +1380,8 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
         UNLOCK_INODE_MUTEX(inode);
         if (ia_valid & ATTR_SIZE)
                 UP_WRITE_I_ALLOC_SEM(inode);
-        cfs_down_write(&lli->lli_trunc_sem);
+        if (!S_ISDIR(inode->i_mode))
+                cfs_down_write(&lli->lli_trunc_sem);
         LOCK_INODE_MUTEX(inode);
         if (ia_valid & ATTR_SIZE)
                 DOWN_WRITE_I_ALLOC_SEM(inode);
@@ -1359,7 +1393,7 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
             (ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MTIME_SET)))
                 op_data->op_flags = MF_EPOCH_OPEN;
 
-        rc = ll_md_setattr(inode, op_data, &mod);
+        rc = ll_md_setattr(dentry, op_data, &mod);
         if (rc)
                 GOTO(out, rc);
 
@@ -1388,7 +1422,8 @@ out:
                         rc1 = ll_setattr_done_writing(inode, op_data, mod);
                 ll_finish_md_op_data(op_data);
         }
-        cfs_up_write(&lli->lli_trunc_sem);
+        if (!S_ISDIR(inode->i_mode))
+                cfs_up_write(&lli->lli_trunc_sem);
         return rc ? rc : rc1;
 }
 
@@ -1417,7 +1452,7 @@ int ll_setattr(struct dentry *de, struct iattr *attr)
             !(attr->ia_valid & ATTR_KILL_SGID))
                 attr->ia_valid |= ATTR_KILL_SGID;
 
-        return ll_setattr_raw(de->d_inode, attr);
+        return ll_setattr_raw(de, attr);
 }
 
 int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
@@ -1519,6 +1554,8 @@ void ll_inode_size_lock(struct inode *inode, int lock_lsm)
         struct ll_inode_info *lli;
         struct lov_stripe_md *lsm;
 
+        LASSERT(!S_ISDIR(inode->i_mode));
+
         lli = ll_i2info(inode);
         LASSERT(lli->lli_size_sem_owner != current);
         cfs_down(&lli->lli_size_sem);
@@ -1556,6 +1593,8 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
 
         LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
         if (lsm != NULL) {
+                LASSERT(S_ISREG(inode->i_mode));
+
                 cfs_down(&lli->lli_och_sem);
                 if (lli->lli_smd == NULL) {
                         if (lsm->lsm_magic != LOV_MAGIC_V1 &&
@@ -1565,11 +1604,11 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
                         }
                         CDEBUG(D_INODE, "adding lsm %p to inode %lu/%u(%p)\n",
                                lsm, inode->i_ino, inode->i_generation, inode);
-                        /* cl_inode_init must go before lli_smd or a race is
-                         * possible where client thinks the file has stripes,
+                        /* cl_file_inode_init must go before lli_smd or a race
+                         * is possible where client thinks the file has stripes,
                          * but lov raid0 is not setup yet and parallel e.g.
                          * glimpse would try to use uninitialized lov */
-                        cl_inode_init(inode, md);
+                        cl_file_inode_init(inode, md);
                         cfs_spin_lock(&lli->lli_lock);
                         lli->lli_smd = lsm;
                         cfs_spin_unlock(&lli->lli_lock);
@@ -1685,14 +1724,14 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
                                 if (lli->lli_flags & (LLIF_DONE_WRITING |
                                                       LLIF_EPOCH_PENDING |
                                                       LLIF_SOM_DIRTY)) {
-                                        CERROR("ino %lu flags %lu still has "
+                                        CERROR("ino %lu flags %u still has "
                                                "size authority! do not trust "
                                                "the size got from MDS\n",
                                                inode->i_ino, lli->lli_flags);
                                 } else {
                                         /* Use old size assignment to avoid
                                          * deadlock bz14138 & bz14326 */
-                                        inode->i_size = body->size;
+                                        i_size_write(inode, body->size);
                                         lli->lli_flags |= LLIF_MDS_SIZE_LOCK;
                                 }
                                 ldlm_lock_decref(&lockh, mode);
@@ -1700,7 +1739,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
                 } else {
                         /* Use old size assignment to avoid
                          * deadlock bz14138 & bz14326 */
-                        inode->i_size = body->size;
+                        i_size_write(inode, body->size);
 
                         CDEBUG(D_VFSTRACE, "inode=%lu, updating i_size %llu\n",
                                inode->i_ino, (unsigned long long)body->size);
@@ -1729,8 +1768,6 @@ void ll_read_inode2(struct inode *inode, void *opaque)
         CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
                PFID(&lli->lli_fid), inode);
 
-        ll_lli_init(lli);
-
         LASSERT(!lli->lli_smd);
 
         /* Core attributes from the MDS first.  This is a new inode, and
@@ -1797,7 +1834,12 @@ void ll_delete_inode(struct inode *inode)
         }
         /* Workaround end */
 
+#ifdef HAVE_SBOPS_EVICT_INODE
+        ll_clear_inode(inode);
+        end_writeback(inode);
+#else
         clear_inode(inode);
+#endif
 
         EXIT;
 }
@@ -2095,7 +2137,7 @@ int ll_obd_statfs(struct inode *inode, void *arg)
                 GOTO(out_statfs, rc = -EINVAL);
 
         memcpy(&type, data->ioc_inlbuf1, sizeof(__u32));
-        if (type == LL_STATFS_MDC)
+        if (type == LL_STATFS_LMV)
                 exp = sbi->ll_md_exp;
         else if (type == LL_STATFS_LOV)
                 exp = sbi->ll_dt_exp;
@@ -2230,3 +2272,29 @@ int ll_show_options(struct seq_file *seq, struct vfsmount *vfs)
 
         RETURN(0);
 }
+
+/**
+ * Get obd name by cmd, and copy out to user space
+ */
+int ll_get_obd_name(struct inode *inode, unsigned int cmd, unsigned long arg)
+{
+        struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct obd_device *obd;
+        ENTRY;
+
+        if (cmd == OBD_IOC_GETDTNAME)
+                obd = class_exp2obd(sbi->ll_dt_exp);
+        else if (cmd == OBD_IOC_GETMDNAME)
+                obd = class_exp2obd(sbi->ll_md_exp);
+        else
+                RETURN(-EINVAL);
+
+        if (!obd)
+                RETURN(-ENOENT);
+
+        if (cfs_copy_to_user((void *)arg, obd->obd_name,
+                             strlen(obd->obd_name) + 1))
+                RETURN(-EFAULT);
+
+        RETURN(0);
+}