diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/dir-item.c | 9 | ||||
-rw-r--r-- | fs/btrfs/xattr.c | 66 |
2 files changed, 42 insertions, 33 deletions
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c index 685f2593c4f0..c360a848d97f 100644 --- a/fs/btrfs/dir-item.c +++ b/fs/btrfs/dir-item.c | |||
@@ -89,13 +89,8 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, | |||
89 | data_size = sizeof(*dir_item) + name_len + data_len; | 89 | data_size = sizeof(*dir_item) + name_len + data_len; |
90 | dir_item = insert_with_overflow(trans, root, path, &key, data_size, | 90 | dir_item = insert_with_overflow(trans, root, path, &key, data_size, |
91 | name, name_len); | 91 | name, name_len); |
92 | /* | 92 | if (IS_ERR(dir_item)) |
93 | * FIXME: at some point we should handle xattr's that are larger than | 93 | return PTR_ERR(dir_item); |
94 | * what we can fit in our leaf. We set location to NULL b/c we arent | ||
95 | * pointing at anything else, that will change if we store the xattr | ||
96 | * data in a separate inode. | ||
97 | */ | ||
98 | BUG_ON(IS_ERR(dir_item)); | ||
99 | memset(&location, 0, sizeof(location)); | 94 | memset(&location, 0, sizeof(location)); |
100 | 95 | ||
101 | leaf = path->nodes[0]; | 96 | leaf = path->nodes[0]; |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 5366fe452ab0..d733b9cfea34 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
@@ -102,43 +102,57 @@ static int do_setxattr(struct btrfs_trans_handle *trans, | |||
102 | if (!path) | 102 | if (!path) |
103 | return -ENOMEM; | 103 | return -ENOMEM; |
104 | 104 | ||
105 | /* first lets see if we already have this xattr */ | 105 | if (flags & XATTR_REPLACE) { |
106 | di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name, | 106 | di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name, |
107 | strlen(name), -1); | 107 | name_len, -1); |
108 | if (IS_ERR(di)) { | 108 | if (IS_ERR(di)) { |
109 | ret = PTR_ERR(di); | 109 | ret = PTR_ERR(di); |
110 | goto out; | 110 | goto out; |
111 | } | 111 | } else if (!di) { |
112 | 112 | ret = -ENODATA; | |
113 | /* ok we already have this xattr, lets remove it */ | ||
114 | if (di) { | ||
115 | /* if we want create only exit */ | ||
116 | if (flags & XATTR_CREATE) { | ||
117 | ret = -EEXIST; | ||
118 | goto out; | 113 | goto out; |
119 | } | 114 | } |
120 | |||
121 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | 115 | ret = btrfs_delete_one_dir_name(trans, root, path, di); |
122 | BUG_ON(ret); | 116 | if (ret) |
117 | goto out; | ||
123 | btrfs_release_path(path); | 118 | btrfs_release_path(path); |
119 | } | ||
124 | 120 | ||
125 | /* if we don't have a value then we are removing the xattr */ | 121 | again: |
126 | if (!value) | 122 | ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), |
123 | name, name_len, value, size); | ||
124 | if (ret == -EEXIST) { | ||
125 | if (flags & XATTR_CREATE) | ||
127 | goto out; | 126 | goto out; |
128 | } else { | 127 | /* |
128 | * We can't use the path we already have since we won't have the | ||
129 | * proper locking for a delete, so release the path and | ||
130 | * re-lookup to delete the thing. | ||
131 | */ | ||
129 | btrfs_release_path(path); | 132 | btrfs_release_path(path); |
133 | di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), | ||
134 | name, name_len, -1); | ||
135 | if (IS_ERR(di)) { | ||
136 | ret = PTR_ERR(di); | ||
137 | goto out; | ||
138 | } else if (!di) { | ||
139 | /* Shouldn't happen but just in case... */ | ||
140 | btrfs_release_path(path); | ||
141 | goto again; | ||
142 | } | ||
130 | 143 | ||
131 | if (flags & XATTR_REPLACE) { | 144 | ret = btrfs_delete_one_dir_name(trans, root, path, di); |
132 | /* we couldn't find the attr to replace */ | 145 | if (ret) |
133 | ret = -ENODATA; | ||
134 | goto out; | 146 | goto out; |
147 | |||
148 | /* | ||
149 | * We have a value to set, so go back and try to insert it now. | ||
150 | */ | ||
151 | if (value) { | ||
152 | btrfs_release_path(path); | ||
153 | goto again; | ||
135 | } | 154 | } |
136 | } | 155 | } |
137 | |||
138 | /* ok we have to create a completely new xattr */ | ||
139 | ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), | ||
140 | name, name_len, value, size); | ||
141 | BUG_ON(ret); | ||
142 | out: | 156 | out: |
143 | btrfs_free_path(path); | 157 | btrfs_free_path(path); |
144 | return ret; | 158 | return ret; |