aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/acl.c11
-rw-r--r--fs/ceph/dir.c23
-rw-r--r--fs/ceph/file.c1
-rw-r--r--fs/ceph/super.c32
-rw-r--r--fs/ceph/super.h7
-rw-r--r--fs/ceph/xattr.c54
6 files changed, 93 insertions, 35 deletions
diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c
index 4c2d452c4bfc..21887d63dad5 100644
--- a/fs/ceph/acl.c
+++ b/fs/ceph/acl.c
@@ -54,11 +54,6 @@ static inline struct posix_acl *ceph_get_cached_acl(struct inode *inode,
54 return acl; 54 return acl;
55} 55}
56 56
57void ceph_forget_all_cached_acls(struct inode *inode)
58{
59 forget_all_cached_acls(inode);
60}
61
62struct posix_acl *ceph_get_acl(struct inode *inode, int type) 57struct posix_acl *ceph_get_acl(struct inode *inode, int type)
63{ 58{
64 int size; 59 int size;
@@ -160,11 +155,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
160 goto out_dput; 155 goto out_dput;
161 } 156 }
162 157
163 if (value) 158 ret = __ceph_setxattr(dentry, name, value, size, 0);
164 ret = __ceph_setxattr(dentry, name, value, size, 0);
165 else
166 ret = __ceph_removexattr(dentry, name);
167
168 if (ret) { 159 if (ret) {
169 if (new_mode != old_mode) { 160 if (new_mode != old_mode) {
170 newattrs.ia_mode = old_mode; 161 newattrs.ia_mode = old_mode;
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 6da4df84ba30..45eda6d7a40c 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -100,6 +100,14 @@ static unsigned fpos_off(loff_t p)
100 return p & 0xffffffff; 100 return p & 0xffffffff;
101} 101}
102 102
103static int fpos_cmp(loff_t l, loff_t r)
104{
105 int v = ceph_frag_compare(fpos_frag(l), fpos_frag(r));
106 if (v)
107 return v;
108 return (int)(fpos_off(l) - fpos_off(r));
109}
110
103/* 111/*
104 * When possible, we try to satisfy a readdir by peeking at the 112 * When possible, we try to satisfy a readdir by peeking at the
105 * dcache. We make this work by carefully ordering dentries on 113 * dcache. We make this work by carefully ordering dentries on
@@ -156,7 +164,7 @@ more:
156 if (!d_unhashed(dentry) && dentry->d_inode && 164 if (!d_unhashed(dentry) && dentry->d_inode &&
157 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && 165 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
158 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && 166 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
159 ctx->pos <= di->offset) 167 fpos_cmp(ctx->pos, di->offset) <= 0)
160 break; 168 break;
161 dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry, 169 dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry,
162 dentry->d_name.len, dentry->d_name.name, di->offset, 170 dentry->d_name.len, dentry->d_name.name, di->offset,
@@ -695,9 +703,8 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
695 ceph_mdsc_put_request(req); 703 ceph_mdsc_put_request(req);
696 704
697 if (!err) 705 if (!err)
698 err = ceph_init_acl(dentry, dentry->d_inode, dir); 706 ceph_init_acl(dentry, dentry->d_inode, dir);
699 707 else
700 if (err)
701 d_drop(dentry); 708 d_drop(dentry);
702 return err; 709 return err;
703} 710}
@@ -735,7 +742,9 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
735 if (!err && !req->r_reply_info.head->is_dentry) 742 if (!err && !req->r_reply_info.head->is_dentry)
736 err = ceph_handle_notrace_create(dir, dentry); 743 err = ceph_handle_notrace_create(dir, dentry);
737 ceph_mdsc_put_request(req); 744 ceph_mdsc_put_request(req);
738 if (err) 745 if (!err)
746 ceph_init_acl(dentry, dentry->d_inode, dir);
747 else
739 d_drop(dentry); 748 d_drop(dentry);
740 return err; 749 return err;
741} 750}
@@ -776,7 +785,9 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
776 err = ceph_handle_notrace_create(dir, dentry); 785 err = ceph_handle_notrace_create(dir, dentry);
777 ceph_mdsc_put_request(req); 786 ceph_mdsc_put_request(req);
778out: 787out:
779 if (err < 0) 788 if (!err)
789 ceph_init_acl(dentry, dentry->d_inode, dir);
790 else
780 d_drop(dentry); 791 d_drop(dentry);
781 return err; 792 return err;
782} 793}
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index dfd2ce3419f8..09c7afe32e49 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -286,6 +286,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
286 } else { 286 } else {
287 dout("atomic_open finish_open on dn %p\n", dn); 287 dout("atomic_open finish_open on dn %p\n", dn);
288 if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) { 288 if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) {
289 ceph_init_acl(dentry, dentry->d_inode, dir);
289 *opened |= FILE_CREATED; 290 *opened |= FILE_CREATED;
290 } 291 }
291 err = finish_open(file, dentry, ceph_open, opened); 292 err = finish_open(file, dentry, ceph_open, opened);
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 2df963f1cf5a..10a4ccbf38da 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -144,7 +144,11 @@ enum {
144 Opt_ino32, 144 Opt_ino32,
145 Opt_noino32, 145 Opt_noino32,
146 Opt_fscache, 146 Opt_fscache,
147 Opt_nofscache 147 Opt_nofscache,
148#ifdef CONFIG_CEPH_FS_POSIX_ACL
149 Opt_acl,
150#endif
151 Opt_noacl
148}; 152};
149 153
150static match_table_t fsopt_tokens = { 154static match_table_t fsopt_tokens = {
@@ -172,6 +176,10 @@ static match_table_t fsopt_tokens = {
172 {Opt_noino32, "noino32"}, 176 {Opt_noino32, "noino32"},
173 {Opt_fscache, "fsc"}, 177 {Opt_fscache, "fsc"},
174 {Opt_nofscache, "nofsc"}, 178 {Opt_nofscache, "nofsc"},
179#ifdef CONFIG_CEPH_FS_POSIX_ACL
180 {Opt_acl, "acl"},
181#endif
182 {Opt_noacl, "noacl"},
175 {-1, NULL} 183 {-1, NULL}
176}; 184};
177 185
@@ -271,6 +279,14 @@ static int parse_fsopt_token(char *c, void *private)
271 case Opt_nofscache: 279 case Opt_nofscache:
272 fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE; 280 fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE;
273 break; 281 break;
282#ifdef CONFIG_CEPH_FS_POSIX_ACL
283 case Opt_acl:
284 fsopt->sb_flags |= MS_POSIXACL;
285 break;
286#endif
287 case Opt_noacl:
288 fsopt->sb_flags &= ~MS_POSIXACL;
289 break;
274 default: 290 default:
275 BUG_ON(token); 291 BUG_ON(token);
276 } 292 }
@@ -438,6 +454,13 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root)
438 else 454 else
439 seq_puts(m, ",nofsc"); 455 seq_puts(m, ",nofsc");
440 456
457#ifdef CONFIG_CEPH_FS_POSIX_ACL
458 if (fsopt->sb_flags & MS_POSIXACL)
459 seq_puts(m, ",acl");
460 else
461 seq_puts(m, ",noacl");
462#endif
463
441 if (fsopt->wsize) 464 if (fsopt->wsize)
442 seq_printf(m, ",wsize=%d", fsopt->wsize); 465 seq_printf(m, ",wsize=%d", fsopt->wsize);
443 if (fsopt->rsize != CEPH_RSIZE_DEFAULT) 466 if (fsopt->rsize != CEPH_RSIZE_DEFAULT)
@@ -819,9 +842,6 @@ static int ceph_set_super(struct super_block *s, void *data)
819 842
820 s->s_flags = fsc->mount_options->sb_flags; 843 s->s_flags = fsc->mount_options->sb_flags;
821 s->s_maxbytes = 1ULL << 40; /* temp value until we get mdsmap */ 844 s->s_maxbytes = 1ULL << 40; /* temp value until we get mdsmap */
822#ifdef CONFIG_CEPH_FS_POSIX_ACL
823 s->s_flags |= MS_POSIXACL;
824#endif
825 845
826 s->s_xattr = ceph_xattr_handlers; 846 s->s_xattr = ceph_xattr_handlers;
827 s->s_fs_info = fsc; 847 s->s_fs_info = fsc;
@@ -911,6 +931,10 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type,
911 struct ceph_options *opt = NULL; 931 struct ceph_options *opt = NULL;
912 932
913 dout("ceph_mount\n"); 933 dout("ceph_mount\n");
934
935#ifdef CONFIG_CEPH_FS_POSIX_ACL
936 flags |= MS_POSIXACL;
937#endif
914 err = parse_mount_options(&fsopt, &opt, flags, data, dev_name, &path); 938 err = parse_mount_options(&fsopt, &opt, flags, data, dev_name, &path);
915 if (err < 0) { 939 if (err < 0) {
916 res = ERR_PTR(err); 940 res = ERR_PTR(err);
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 19793b56d0a7..d8801a95b685 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -13,6 +13,7 @@
13#include <linux/wait.h> 13#include <linux/wait.h>
14#include <linux/writeback.h> 14#include <linux/writeback.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/posix_acl.h>
16 17
17#include <linux/ceph/libceph.h> 18#include <linux/ceph/libceph.h>
18 19
@@ -743,7 +744,11 @@ extern const struct xattr_handler *ceph_xattr_handlers[];
743struct posix_acl *ceph_get_acl(struct inode *, int); 744struct posix_acl *ceph_get_acl(struct inode *, int);
744int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type); 745int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type);
745int ceph_init_acl(struct dentry *, struct inode *, struct inode *); 746int ceph_init_acl(struct dentry *, struct inode *, struct inode *);
746void ceph_forget_all_cached_acls(struct inode *inode); 747
748static inline void ceph_forget_all_cached_acls(struct inode *inode)
749{
750 forget_all_cached_acls(inode);
751}
747 752
748#else 753#else
749 754
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
index 898b6565ad3e..a55ec37378c6 100644
--- a/fs/ceph/xattr.c
+++ b/fs/ceph/xattr.c
@@ -12,6 +12,9 @@
12#define XATTR_CEPH_PREFIX "ceph." 12#define XATTR_CEPH_PREFIX "ceph."
13#define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1) 13#define XATTR_CEPH_PREFIX_LEN (sizeof (XATTR_CEPH_PREFIX) - 1)
14 14
15static int __remove_xattr(struct ceph_inode_info *ci,
16 struct ceph_inode_xattr *xattr);
17
15/* 18/*
16 * List of handlers for synthetic system.* attributes. Other 19 * List of handlers for synthetic system.* attributes. Other
17 * attributes are handled directly. 20 * attributes are handled directly.
@@ -319,8 +322,7 @@ static struct ceph_vxattr *ceph_match_vxattr(struct inode *inode,
319static int __set_xattr(struct ceph_inode_info *ci, 322static int __set_xattr(struct ceph_inode_info *ci,
320 const char *name, int name_len, 323 const char *name, int name_len,
321 const char *val, int val_len, 324 const char *val, int val_len,
322 int dirty, 325 int flags, int update_xattr,
323 int should_free_name, int should_free_val,
324 struct ceph_inode_xattr **newxattr) 326 struct ceph_inode_xattr **newxattr)
325{ 327{
326 struct rb_node **p; 328 struct rb_node **p;
@@ -349,12 +351,31 @@ static int __set_xattr(struct ceph_inode_info *ci,
349 xattr = NULL; 351 xattr = NULL;
350 } 352 }
351 353
354 if (update_xattr) {
355 int err = 0;
356 if (xattr && (flags & XATTR_CREATE))
357 err = -EEXIST;
358 else if (!xattr && (flags & XATTR_REPLACE))
359 err = -ENODATA;
360 if (err) {
361 kfree(name);
362 kfree(val);
363 return err;
364 }
365 if (update_xattr < 0) {
366 if (xattr)
367 __remove_xattr(ci, xattr);
368 kfree(name);
369 return 0;
370 }
371 }
372
352 if (!xattr) { 373 if (!xattr) {
353 new = 1; 374 new = 1;
354 xattr = *newxattr; 375 xattr = *newxattr;
355 xattr->name = name; 376 xattr->name = name;
356 xattr->name_len = name_len; 377 xattr->name_len = name_len;
357 xattr->should_free_name = should_free_name; 378 xattr->should_free_name = update_xattr;
358 379
359 ci->i_xattrs.count++; 380 ci->i_xattrs.count++;
360 dout("__set_xattr count=%d\n", ci->i_xattrs.count); 381 dout("__set_xattr count=%d\n", ci->i_xattrs.count);
@@ -364,7 +385,7 @@ static int __set_xattr(struct ceph_inode_info *ci,
364 if (xattr->should_free_val) 385 if (xattr->should_free_val)
365 kfree((void *)xattr->val); 386 kfree((void *)xattr->val);
366 387
367 if (should_free_name) { 388 if (update_xattr) {
368 kfree((void *)name); 389 kfree((void *)name);
369 name = xattr->name; 390 name = xattr->name;
370 } 391 }
@@ -379,8 +400,8 @@ static int __set_xattr(struct ceph_inode_info *ci,
379 xattr->val = ""; 400 xattr->val = "";
380 401
381 xattr->val_len = val_len; 402 xattr->val_len = val_len;
382 xattr->dirty = dirty; 403 xattr->dirty = update_xattr;
383 xattr->should_free_val = (val && should_free_val); 404 xattr->should_free_val = (val && update_xattr);
384 405
385 if (new) { 406 if (new) {
386 rb_link_node(&xattr->node, parent, p); 407 rb_link_node(&xattr->node, parent, p);
@@ -442,7 +463,7 @@ static int __remove_xattr(struct ceph_inode_info *ci,
442 struct ceph_inode_xattr *xattr) 463 struct ceph_inode_xattr *xattr)
443{ 464{
444 if (!xattr) 465 if (!xattr)
445 return -EOPNOTSUPP; 466 return -ENODATA;
446 467
447 rb_erase(&xattr->node, &ci->i_xattrs.index); 468 rb_erase(&xattr->node, &ci->i_xattrs.index);
448 469
@@ -588,7 +609,7 @@ start:
588 p += len; 609 p += len;
589 610
590 err = __set_xattr(ci, name, namelen, val, len, 611 err = __set_xattr(ci, name, namelen, val, len,
591 0, 0, 0, &xattrs[numattr]); 612 0, 0, &xattrs[numattr]);
592 613
593 if (err < 0) 614 if (err < 0)
594 goto bad; 615 goto bad;
@@ -850,6 +871,9 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
850 871
851 dout("setxattr value=%.*s\n", (int)size, value); 872 dout("setxattr value=%.*s\n", (int)size, value);
852 873
874 if (!value)
875 flags |= CEPH_XATTR_REMOVE;
876
853 /* do request */ 877 /* do request */
854 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, 878 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR,
855 USE_AUTH_MDS); 879 USE_AUTH_MDS);
@@ -892,7 +916,7 @@ int __ceph_setxattr(struct dentry *dentry, const char *name,
892 struct ceph_inode_info *ci = ceph_inode(inode); 916 struct ceph_inode_info *ci = ceph_inode(inode);
893 int issued; 917 int issued;
894 int err; 918 int err;
895 int dirty; 919 int dirty = 0;
896 int name_len = strlen(name); 920 int name_len = strlen(name);
897 int val_len = size; 921 int val_len = size;
898 char *newname = NULL; 922 char *newname = NULL;
@@ -953,12 +977,14 @@ retry:
953 goto retry; 977 goto retry;
954 } 978 }
955 979
956 err = __set_xattr(ci, newname, name_len, newval, 980 err = __set_xattr(ci, newname, name_len, newval, val_len,
957 val_len, 1, 1, 1, &xattr); 981 flags, value ? 1 : -1, &xattr);
958 982
959 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); 983 if (!err) {
960 ci->i_xattrs.dirty = true; 984 dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL);
961 inode->i_ctime = CURRENT_TIME; 985 ci->i_xattrs.dirty = true;
986 inode->i_ctime = CURRENT_TIME;
987 }
962 988
963 spin_unlock(&ci->i_ceph_lock); 989 spin_unlock(&ci->i_ceph_lock);
964 if (dirty) 990 if (dirty)