]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: send xattrs blob when dropping xattr rdcache
authorYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 14 Apr 2009 22:11:27 +0000 (15:11 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 16 Apr 2009 21:46:34 +0000 (14:46 -0700)
src/include/ceph_fs.h
src/kernel/caps.c
src/kernel/inode.c
src/kernel/super.h

index 0fd2de5beaaff24a6fd157f7015eefda3277b828..8f94807d7076a6fb6ad732c45934b526d709c3d6 100644 (file)
@@ -1075,6 +1075,10 @@ struct ceph_mds_caps {
        struct ceph_timespec mtime, atime, ctime;
        struct ceph_file_layout layout;
        __le32 time_warp_seq;
+
+       /* xattrs */
+       __le32 xattrs_blob_size;
+       char xattrs_blob[0];
 } __attribute__ ((packed));
 
 struct ceph_mds_cap_release {
index 2d0d840eaa3cbec8103c8b8d6522b17b31d1996c..cf533b6a8ea2501c9038941b0921228420435555 100644 (file)
@@ -699,6 +699,7 @@ static void send_cap_msg(struct ceph_mds_client *mdsc, u64 ino, u64 cid, int op,
                         struct timespec *mtime, struct timespec *atime,
                         u64 time_warp_seq,
                         uid_t uid, gid_t gid, mode_t mode,
+                        void *xattrs_blob, int xattrs_blob_size,
                         u64 follows, int mds)
 {
        struct ceph_mds_caps *fc;
@@ -710,7 +711,7 @@ static void send_cap_msg(struct ceph_mds_client *mdsc, u64 ino, u64 cid, int op,
             ceph_cap_string(dirty),
             seq, mseq, follows, size);
 
-       msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc), 0, 0, NULL);
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc) + xattrs_blob_size, 0, 0, NULL);
        if (IS_ERR(msg))
                return;
 
@@ -740,6 +741,9 @@ static void send_cap_msg(struct ceph_mds_client *mdsc, u64 ino, u64 cid, int op,
        fc->gid = cpu_to_le32(gid);
        fc->mode = cpu_to_le32(mode);
 
+       fc->xattrs_blob_size = xattrs_blob_size;
+       memcpy(&fc->xattrs_blob[0],  xattrs_blob, xattrs_blob_size);
+
        ceph_send_msg_mds(mdsc, msg, mds);
 }
 
@@ -827,6 +831,8 @@ static void __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
        uid_t uid;
        gid_t gid;
        int mds = cap->session->s_mds;
+       void *xattrs_blob;
+       int xattrs_blob_size;
 
        dout(10, "__send_cap cap %p session %p %s -> %s (revoking %s)\n",
             cap, cap->session,
@@ -873,6 +879,14 @@ static void __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
        uid = inode->i_uid;
        gid = inode->i_gid;
        mode = inode->i_mode;
+
+       if (dropping & CEPH_CAP_XATTR_RDCACHE) {
+               __ceph_build_xattrs_blob(ci, &xattrs_blob, &xattrs_blob_size);
+               ci->i_xattrs.prealloc_blob = 0;
+               ci->i_xattrs.prealloc_size = 0;
+       } else {
+               xattrs_blob = NULL;
+       }
        spin_unlock(&inode->i_lock);
 
        if (dropping & CEPH_CAP_FILE_RDCACHE) {
@@ -885,8 +899,12 @@ static void __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
                     op, keep, want, flushing, seq, mseq,
                     size, max_size, &mtime, &atime, time_warp_seq,
                     uid, gid, mode,
+                    xattrs_blob, xattrs_blob_size,
                     follows, mds);
 
+       if (xattrs_blob)
+               kfree(xattrs_blob);
+
        if (wake)
                wake_up(&ci->i_cap_wq);
 }
@@ -972,6 +990,7 @@ retry:
                             &capsnap->mtime, &capsnap->atime,
                             capsnap->time_warp_seq,
                             capsnap->uid, capsnap->gid, capsnap->mode,
+                            NULL, 0,
                             capsnap->follows, mds);
 
                next_follows = capsnap->follows + 1;
index 97dcf21551bd665b99e21cd8b1fcb3d51a6129dc..ce8778e345c8786faecd189b0821c8064c93c177 100644 (file)
@@ -1894,14 +1894,25 @@ bad:
        return err;
 }
 
-void *__ceph_build_xattrs_blob(struct ceph_inode_info *ci)
+int __get_required_blob_size(struct ceph_inode_info *ci)
+{
+       return  4 + ci->i_xattrs.count*(4 + 4) +
+                            ci->i_xattrs.names_size +
+                            ci->i_xattrs.vals_size;
+}
+
+void __ceph_build_xattrs_blob(struct ceph_inode_info *ci,
+                             void **xattrs_blob,
+                             int *blob_size)
 {
        struct rb_node *p;
        struct ceph_inode_xattr *xattr = NULL;
        void *dest;
 
        if (ci->i_xattrs.names_size) {
-               BUG_ON(!ci->i_xattrs.prealloc_blob);
+               int required_blob_size = __get_required_blob_size(ci);
+
+               BUG_ON(required_blob_size > ci->i_xattrs.prealloc_size);
 
                p = rb_first(&ci->i_xattrs.xattrs);
 
@@ -1921,10 +1932,13 @@ void *__ceph_build_xattrs_blob(struct ceph_inode_info *ci)
                        p = rb_next(p);
                }
        
-               return ci->i_xattrs.prealloc_blob;
+               *xattrs_blob =  ci->i_xattrs.prealloc_blob;
+               *blob_size = ci->i_xattrs.prealloc_size;
        } else {
-               /*just use the blob that we hold */
-               return ci->i_xattrs.data;
+               /* actually, we're using the same data that we got from the
+                  mds, don't build anything */
+               *xattrs_blob = NULL;
+               *blob_size = 0;
        }
 }
 
@@ -2083,13 +2097,6 @@ out:
        return err;
 }
 
-int __get_required_blob_size(struct ceph_inode_info *ci)
-{
-       return  4 + ci->i_xattrs.count*(4 + 4) +
-                            ci->i_xattrs.names_size +
-                            ci->i_xattrs.vals_size;
-}
-
 int ceph_setxattr(struct dentry *dentry, const char *name,
                  const void *value, size_t size, int flags)
 {
index d93f4ccce951eea1a982e1a3251500e9c0032f6a..e458cc0a9bead68f8931080240b4b6a07f412dc0 100644 (file)
@@ -795,6 +795,9 @@ extern int ceph_setxattr(struct dentry *, const char *, const void *,
 extern ssize_t ceph_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t ceph_listxattr(struct dentry *, char *, size_t);
 extern int ceph_removexattr(struct dentry *, const char *);
+extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci,
+                                     void **xattrs_blob,
+                                     int *blob_size);
 
 /* caps.c */
 extern const char *ceph_cap_string(int c);