crypto: crypto4xx - fix dynamic_sa_ctl's sa_contents declaration
[linux-2.6-microblaze.git] / fs / ceph / caps.c
index 7007ae2..157fe59 100644 (file)
@@ -490,13 +490,14 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
        }
 
        /*
-        * if we are newly issued FILE_SHARED, mark dir not complete; we
-        * don't know what happened to this directory while we didn't
-        * have the cap.
+        * If FILE_SHARED is newly issued, mark dir not complete. We don't
+        * know what happened to this directory while we didn't have the cap.
+        * If FILE_SHARED is being revoked, also mark dir not complete. It
+        * stops on-going cached readdir.
         */
-       if ((issued & CEPH_CAP_FILE_SHARED) &&
-           (had & CEPH_CAP_FILE_SHARED) == 0) {
-               ci->i_shared_gen++;
+       if ((issued & CEPH_CAP_FILE_SHARED) != (had & CEPH_CAP_FILE_SHARED)) {
+               if (issued & CEPH_CAP_FILE_SHARED)
+                       ci->i_shared_gen++;
                if (S_ISDIR(ci->vfs_inode.i_mode)) {
                        dout(" marking %p NOT complete\n", &ci->vfs_inode);
                        __ceph_dir_clear_complete(ci);
@@ -611,7 +612,7 @@ void ceph_add_cap(struct inode *inode,
        }
 
        if (flags & CEPH_CAP_FLAG_AUTH) {
-               if (ci->i_auth_cap == NULL ||
+               if (!ci->i_auth_cap ||
                    ceph_seq_cmp(ci->i_auth_cap->mseq, mseq) < 0) {
                        ci->i_auth_cap = cap;
                        cap->mds_wanted = wanted;
@@ -728,7 +729,7 @@ static void __touch_cap(struct ceph_cap *cap)
        struct ceph_mds_session *s = cap->session;
 
        spin_lock(&s->s_cap_lock);
-       if (s->s_cap_iterator == NULL) {
+       if (!s->s_cap_iterator) {
                dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap,
                     s->s_mds);
                list_move_tail(&cap->session_caps, &s->s_caps);
@@ -1248,7 +1249,10 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
        arg.mode = inode->i_mode;
 
        arg.inline_data = ci->i_inline_version != CEPH_INLINE_NONE;
-       arg.flags = 0;
+       if (list_empty(&ci->i_cap_snaps))
+               arg.flags = CEPH_CLIENT_CAPS_NO_CAPSNAP;
+       else
+               arg.flags = CEPH_CLIENT_CAPS_PENDING_CAPSNAP;
        if (sync)
                arg.flags |= CEPH_CLIENT_CAPS_SYNC;
 
@@ -1454,13 +1458,19 @@ retry:
                goto retry;
        }
 
+       // make sure flushsnap messages are sent in proper order.
+       if (ci->i_ceph_flags & CEPH_I_KICK_FLUSH) {
+               __kick_flushing_caps(mdsc, session, ci, 0);
+               ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH;
+       }
+
        __ceph_flush_snaps(ci, session);
 out:
        spin_unlock(&ci->i_ceph_lock);
 
        if (psession) {
                *psession = session;
-       } else {
+       } else if (session) {
                mutex_unlock(&session->s_mutex);
                ceph_put_mds_session(session);
        }
@@ -1901,11 +1911,7 @@ ack:
                    (ci->i_ceph_flags &
                     (CEPH_I_KICK_FLUSH | CEPH_I_FLUSH_SNAPS))) {
                        if (ci->i_ceph_flags & CEPH_I_KICK_FLUSH) {
-                               spin_lock(&mdsc->cap_dirty_lock);
-                               oldest_flush_tid = __get_oldest_flush_tid(mdsc);
-                               spin_unlock(&mdsc->cap_dirty_lock);
-                               __kick_flushing_caps(mdsc, session, ci,
-                                                    oldest_flush_tid);
+                               __kick_flushing_caps(mdsc, session, ci, 0);
                                ci->i_ceph_flags &= ~CEPH_I_KICK_FLUSH;
                        }
                        if (ci->i_ceph_flags & CEPH_I_FLUSH_SNAPS)
@@ -2110,7 +2116,7 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 
        dout("fsync %p%s\n", inode, datasync ? " datasync" : "");
 
-       ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+       ret = file_write_and_wait_range(file, start, end);
        if (ret < 0)
                goto out;
 
@@ -3422,7 +3428,7 @@ retry:
        tcap = __get_cap_for_mds(ci, target);
        if (tcap) {
                /* already have caps from the target */
-               if (tcap->cap_id != t_cap_id ||
+               if (tcap->cap_id == t_cap_id &&
                    ceph_seq_cmp(tcap->seq, t_seq) < 0) {
                        dout(" updating import cap %p mds%d\n", tcap, target);
                        tcap->cap_id = t_cap_id;