Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 May 2011 21:22:20 +0000 (14:22 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 May 2011 21:22:20 +0000 (14:22 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
  ceph: do not call __mark_dirty_inode under i_lock
  libceph: fix ceph_osdc_alloc_request error checks
  ceph: handle ceph_osdc_new_request failure in ceph_writepages_start
  libceph: fix ceph_msg_new error path
  ceph: use ihold() when i_lock is held

drivers/block/rbd.c
fs/ceph/addr.c
fs/ceph/caps.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/super.h
fs/ceph/xattr.c
net/ceph/messenger.c
net/ceph/osd_client.c

index 16dc364..3e90471 100644 (file)
@@ -777,9 +777,9 @@ static int rbd_do_request(struct request *rq,
                                      ops,
                                      false,
                                      GFP_NOIO, pages, bio);
-       if (IS_ERR(req)) {
+       if (!req) {
                up_read(&header->snap_rwsem);
-               ret = PTR_ERR(req);
+               ret = -ENOMEM;
                goto done_pages;
        }
 
index e159c52..38b8ab5 100644 (file)
@@ -775,6 +775,13 @@ get_more_pages:
                                            ci->i_truncate_seq,
                                            ci->i_truncate_size,
                                            &inode->i_mtime, true, 1, 0);
+
+                               if (!req) {
+                                       rc = -ENOMEM;
+                                       unlock_page(page);
+                                       break;
+                               }
+
                                max_pages = req->r_num_pages;
 
                                alloc_page_vec(fsc, req);
index 5323c33..9fa0866 100644 (file)
@@ -1331,10 +1331,11 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci)
 }
 
 /*
- * Mark caps dirty.  If inode is newly dirty, add to the global dirty
- * list.
+ * Mark caps dirty.  If inode is newly dirty, return the dirty flags.
+ * Caller is then responsible for calling __mark_inode_dirty with the
+ * returned flags value.
  */
-void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
+int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
 {
        struct ceph_mds_client *mdsc =
                ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc;
@@ -1357,7 +1358,7 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
                list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
                spin_unlock(&mdsc->cap_dirty_lock);
                if (ci->i_flushing_caps == 0) {
-                       igrab(inode);
+                       ihold(inode);
                        dirty |= I_DIRTY_SYNC;
                }
        }
@@ -1365,9 +1366,8 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
        if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
            (mask & CEPH_CAP_FILE_BUFFER))
                dirty |= I_DIRTY_DATASYNC;
-       if (dirty)
-               __mark_inode_dirty(inode, dirty);
        __cap_delay_requeue(mdsc, ci);
+       return dirty;
 }
 
 /*
@@ -1991,7 +1991,7 @@ static void __take_cap_refs(struct ceph_inode_info *ci, int got)
                ci->i_wr_ref++;
        if (got & CEPH_CAP_FILE_BUFFER) {
                if (ci->i_wrbuffer_ref == 0)
-                       igrab(&ci->vfs_inode);
+                       ihold(&ci->vfs_inode);
                ci->i_wrbuffer_ref++;
                dout("__take_cap_refs %p wrbuffer %d -> %d (?)\n",
                     &ci->vfs_inode, ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref);
index 159b512..203252d 100644 (file)
@@ -734,9 +734,12 @@ retry_snap:
                }
        }
        if (ret >= 0) {
+               int dirty;
                spin_lock(&inode->i_lock);
-               __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
+               dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR);
                spin_unlock(&inode->i_lock);
+               if (dirty)
+                       __mark_inode_dirty(inode, dirty);
        }
 
 out:
index b54c97d..03d6daf 100644 (file)
@@ -1567,6 +1567,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
        int release = 0, dirtied = 0;
        int mask = 0;
        int err = 0;
+       int inode_dirty_flags = 0;
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EROFS;
@@ -1725,13 +1726,16 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
                dout("setattr %p ATTR_FILE ... hrm!\n", inode);
 
        if (dirtied) {
-               __ceph_mark_dirty_caps(ci, dirtied);
+               inode_dirty_flags = __ceph_mark_dirty_caps(ci, dirtied);
                inode->i_ctime = CURRENT_TIME;
        }
 
        release &= issued;
        spin_unlock(&inode->i_lock);
 
+       if (inode_dirty_flags)
+               __mark_inode_dirty(inode, inode_dirty_flags);
+
        if (mask) {
                req->r_inode = igrab(inode);
                req->r_inode_drop = release;
index 619fe71..b1f1b8b 100644 (file)
@@ -506,7 +506,7 @@ static inline int __ceph_caps_dirty(struct ceph_inode_info *ci)
 {
        return ci->i_dirty_caps | ci->i_flushing_caps;
 }
-extern void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask);
+extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask);
 
 extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask);
 extern int __ceph_caps_used(struct ceph_inode_info *ci);
index 8c9eba6..f2b6286 100644 (file)
@@ -703,6 +703,7 @@ int ceph_setxattr(struct dentry *dentry, const char *name,
        struct ceph_inode_xattr *xattr = NULL;
        int issued;
        int required_blob_size;
+       int dirty;
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EROFS;
@@ -763,11 +764,12 @@ retry:
        dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued));
        err = __set_xattr(ci, newname, name_len, newval,
                          val_len, 1, 1, 1, &xattr);
-       __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
+       dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
        ci->i_xattrs.dirty = true;
        inode->i_ctime = CURRENT_TIME;
        spin_unlock(&inode->i_lock);
-
+       if (dirty)
+               __mark_inode_dirty(inode, dirty);
        return err;
 
 do_sync:
@@ -810,6 +812,7 @@ int ceph_removexattr(struct dentry *dentry, const char *name)
        struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode);
        int issued;
        int err;
+       int dirty;
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EROFS;
@@ -833,12 +836,13 @@ int ceph_removexattr(struct dentry *dentry, const char *name)
                goto do_sync;
 
        err = __remove_xattr_by_name(ceph_inode(inode), name);
-       __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
+       dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
        ci->i_xattrs.dirty = true;
        inode->i_ctime = CURRENT_TIME;
 
        spin_unlock(&inode->i_lock);
-
+       if (dirty)
+               __mark_inode_dirty(inode, dirty);
        return err;
 do_sync:
        spin_unlock(&inode->i_lock);
index 05f3578..e15a82c 100644 (file)
@@ -2267,6 +2267,19 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags)
        m->more_to_follow = false;
        m->pool = NULL;
 
+       /* middle */
+       m->middle = NULL;
+
+       /* data */
+       m->nr_pages = 0;
+       m->page_alignment = 0;
+       m->pages = NULL;
+       m->pagelist = NULL;
+       m->bio = NULL;
+       m->bio_iter = NULL;
+       m->bio_seg = 0;
+       m->trail = NULL;
+
        /* front */
        if (front_len) {
                if (front_len > PAGE_CACHE_SIZE) {
@@ -2286,19 +2299,6 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags)
        }
        m->front.iov_len = front_len;
 
-       /* middle */
-       m->middle = NULL;
-
-       /* data */
-       m->nr_pages = 0;
-       m->page_alignment = 0;
-       m->pages = NULL;
-       m->pagelist = NULL;
-       m->bio = NULL;
-       m->bio_iter = NULL;
-       m->bio_seg = 0;
-       m->trail = NULL;
-
        dout("ceph_msg_new %p front %d\n", m, front_len);
        return m;
 
index 5a80f41..6b5dda1 100644 (file)
@@ -470,8 +470,8 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
                                         snapc, ops,
                                         use_mempool,
                                         GFP_NOFS, NULL, NULL);
-       if (IS_ERR(req))
-               return req;
+       if (!req)
+               return NULL;
 
        /* calculate max write size */
        calc_layout(osdc, vino, layout, off, plen, req, ops);