diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-07 23:51:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-07 23:51:58 -0400 |
commit | e5fef2a9732580c5bd30c0097f5e9091a3d58ce5 (patch) | |
tree | cb91b5a51f7e451300e06e203a50cbed8aabbc1c /fs/afs | |
parent | 149e703cb8bfcbdae46140b108bb6f7d2407df8f (diff) | |
parent | f5e4546347bc847be30b3cf904db5fc874b3c5dc (diff) |
Merge tag 'afs-next-20190507' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull AFS updates from David Howells:
"A set of fix and development patches for AFS for 5.2.
Summary:
- Fix the AFS file locking so that sqlite can run on an AFS mount and
also so that firefox and gnome can use a homedir that's mounted
through AFS.
This required emulation of fine-grained locking when the server
will only support whole-file locks and no upgrade/downgrade. Four
modes are provided, settable by mount parameter:
"flock=local" - No reference to the server
"flock=openafs" - Fine-grained locks are local-only, whole-file
locks require sufficient server locks
"flock=strict" - All locks require sufficient server locks
"flock=write" - Always get an exclusive server lock
If the volume is a read-only or backup volume, then flock=local for
that volume.
- Log extra information for a couple of cases where the client mucks
up somehow: AFS vnode with undefined type and dir check failure -
in both cases we seem to end up with unfilled data, but the issues
happen infrequently and are difficult to reproduce at will.
- Implement silly rename for unlink() and rename().
- Set i_blocks so that du can get some information about usage.
- Fix xattr handlers to return the right amount of data and to not
overflow buffers.
- Implement getting/setting raw AFS and YFS ACLs as xattrs"
* tag 'afs-next-20190507' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
afs: Implement YFS ACL setting
afs: Get YFS ACLs and information through xattrs
afs: implement acl setting
afs: Get an AFS3 ACL as an xattr
afs: Fix getting the afs.fid xattr
afs: Fix the afs.cell and afs.volume xattr handlers
afs: Calculate i_blocks based on file size
afs: Log more information for "kAFS: AFS vnode with undefined type\n"
afs: Provide mount-time configurable byte-range file locking emulation
afs: Add more tracepoints
afs: Implement sillyrename for unlink and rename
afs: Add directory reload tracepoint
afs: Handle lock rpc ops failing on a file that got deleted
afs: Improve dir check failure reports
afs: Add file locking tracepoints
afs: Further fix file locking
afs: Fix AFS file locking to allow fine grained locks
afs: Calculate lock extend timer from set/extend reply reception
afs: Split wait from afs_make_call()
Diffstat (limited to 'fs/afs')
-rw-r--r-- | fs/afs/Makefile | 1 | ||||
-rw-r--r-- | fs/afs/afs_fs.h | 2 | ||||
-rw-r--r-- | fs/afs/dir.c | 167 | ||||
-rw-r--r-- | fs/afs/dir_silly.c | 239 | ||||
-rw-r--r-- | fs/afs/flock.c | 616 | ||||
-rw-r--r-- | fs/afs/fs_probe.c | 13 | ||||
-rw-r--r-- | fs/afs/fsclient.c | 277 | ||||
-rw-r--r-- | fs/afs/inode.c | 43 | ||||
-rw-r--r-- | fs/afs/internal.h | 64 | ||||
-rw-r--r-- | fs/afs/protocol_yfs.h | 6 | ||||
-rw-r--r-- | fs/afs/rxrpc.c | 33 | ||||
-rw-r--r-- | fs/afs/super.c | 34 | ||||
-rw-r--r-- | fs/afs/vl_probe.c | 14 | ||||
-rw-r--r-- | fs/afs/vlclient.c | 26 | ||||
-rw-r--r-- | fs/afs/xattr.c | 270 | ||||
-rw-r--r-- | fs/afs/yfsclient.c | 329 |
16 files changed, 1761 insertions, 373 deletions
diff --git a/fs/afs/Makefile b/fs/afs/Makefile index 0738e2bf5193..cbf31f6cd177 100644 --- a/fs/afs/Makefile +++ b/fs/afs/Makefile | |||
@@ -13,6 +13,7 @@ kafs-y := \ | |||
13 | cmservice.o \ | 13 | cmservice.o \ |
14 | dir.o \ | 14 | dir.o \ |
15 | dir_edit.o \ | 15 | dir_edit.o \ |
16 | dir_silly.o \ | ||
16 | dynroot.o \ | 17 | dynroot.o \ |
17 | file.o \ | 18 | file.o \ |
18 | flock.o \ | 19 | flock.o \ |
diff --git a/fs/afs/afs_fs.h b/fs/afs/afs_fs.h index ddfa88a7a9c0..18a54ca422f8 100644 --- a/fs/afs/afs_fs.h +++ b/fs/afs/afs_fs.h | |||
@@ -17,8 +17,10 @@ | |||
17 | 17 | ||
18 | enum AFS_FS_Operations { | 18 | enum AFS_FS_Operations { |
19 | FSFETCHDATA = 130, /* AFS Fetch file data */ | 19 | FSFETCHDATA = 130, /* AFS Fetch file data */ |
20 | FSFETCHACL = 131, /* AFS Fetch file ACL */ | ||
20 | FSFETCHSTATUS = 132, /* AFS Fetch file status */ | 21 | FSFETCHSTATUS = 132, /* AFS Fetch file status */ |
21 | FSSTOREDATA = 133, /* AFS Store file data */ | 22 | FSSTOREDATA = 133, /* AFS Store file data */ |
23 | FSSTOREACL = 134, /* AFS Store file ACL */ | ||
22 | FSSTORESTATUS = 135, /* AFS Store file status */ | 24 | FSSTORESTATUS = 135, /* AFS Store file status */ |
23 | FSREMOVEFILE = 136, /* AFS Remove a file */ | 25 | FSREMOVEFILE = 136, /* AFS Remove a file */ |
24 | FSCREATEFILE = 137, /* AFS Create a file */ | 26 | FSCREATEFILE = 137, /* AFS Create a file */ |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 8a2562e3a316..9a466be583d2 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -26,6 +26,7 @@ static int afs_dir_open(struct inode *inode, struct file *file); | |||
26 | static int afs_readdir(struct file *file, struct dir_context *ctx); | 26 | static int afs_readdir(struct file *file, struct dir_context *ctx); |
27 | static int afs_d_revalidate(struct dentry *dentry, unsigned int flags); | 27 | static int afs_d_revalidate(struct dentry *dentry, unsigned int flags); |
28 | static int afs_d_delete(const struct dentry *dentry); | 28 | static int afs_d_delete(const struct dentry *dentry); |
29 | static void afs_d_iput(struct dentry *dentry, struct inode *inode); | ||
29 | static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen, | 30 | static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen, |
30 | loff_t fpos, u64 ino, unsigned dtype); | 31 | loff_t fpos, u64 ino, unsigned dtype); |
31 | static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen, | 32 | static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen, |
@@ -85,6 +86,7 @@ const struct dentry_operations afs_fs_dentry_operations = { | |||
85 | .d_delete = afs_d_delete, | 86 | .d_delete = afs_d_delete, |
86 | .d_release = afs_d_release, | 87 | .d_release = afs_d_release, |
87 | .d_automount = afs_d_automount, | 88 | .d_automount = afs_d_automount, |
89 | .d_iput = afs_d_iput, | ||
88 | }; | 90 | }; |
89 | 91 | ||
90 | struct afs_lookup_one_cookie { | 92 | struct afs_lookup_one_cookie { |
@@ -160,6 +162,38 @@ error: | |||
160 | } | 162 | } |
161 | 163 | ||
162 | /* | 164 | /* |
165 | * Check the contents of a directory that we've just read. | ||
166 | */ | ||
167 | static bool afs_dir_check_pages(struct afs_vnode *dvnode, struct afs_read *req) | ||
168 | { | ||
169 | struct afs_xdr_dir_page *dbuf; | ||
170 | unsigned int i, j, qty = PAGE_SIZE / sizeof(union afs_xdr_dir_block); | ||
171 | |||
172 | for (i = 0; i < req->nr_pages; i++) | ||
173 | if (!afs_dir_check_page(dvnode, req->pages[i], req->actual_len)) | ||
174 | goto bad; | ||
175 | return true; | ||
176 | |||
177 | bad: | ||
178 | pr_warn("DIR %llx:%llx f=%llx l=%llx al=%llx r=%llx\n", | ||
179 | dvnode->fid.vid, dvnode->fid.vnode, | ||
180 | req->file_size, req->len, req->actual_len, req->remain); | ||
181 | pr_warn("DIR %llx %x %x %x\n", | ||
182 | req->pos, req->index, req->nr_pages, req->offset); | ||
183 | |||
184 | for (i = 0; i < req->nr_pages; i++) { | ||
185 | dbuf = kmap(req->pages[i]); | ||
186 | for (j = 0; j < qty; j++) { | ||
187 | union afs_xdr_dir_block *block = &dbuf->blocks[j]; | ||
188 | |||
189 | pr_warn("[%02x] %32phN\n", i * qty + j, block); | ||
190 | } | ||
191 | kunmap(req->pages[i]); | ||
192 | } | ||
193 | return false; | ||
194 | } | ||
195 | |||
196 | /* | ||
163 | * open an AFS directory file | 197 | * open an AFS directory file |
164 | */ | 198 | */ |
165 | static int afs_dir_open(struct inode *inode, struct file *file) | 199 | static int afs_dir_open(struct inode *inode, struct file *file) |
@@ -277,6 +311,7 @@ retry: | |||
277 | goto error; | 311 | goto error; |
278 | 312 | ||
279 | if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { | 313 | if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { |
314 | trace_afs_reload_dir(dvnode); | ||
280 | ret = afs_fetch_data(dvnode, key, req); | 315 | ret = afs_fetch_data(dvnode, key, req); |
281 | if (ret < 0) | 316 | if (ret < 0) |
282 | goto error_unlock; | 317 | goto error_unlock; |
@@ -288,10 +323,8 @@ retry: | |||
288 | 323 | ||
289 | /* Validate the data we just read. */ | 324 | /* Validate the data we just read. */ |
290 | ret = -EIO; | 325 | ret = -EIO; |
291 | for (i = 0; i < req->nr_pages; i++) | 326 | if (!afs_dir_check_pages(dvnode, req)) |
292 | if (!afs_dir_check_page(dvnode, req->pages[i], | 327 | goto error_unlock; |
293 | req->actual_len)) | ||
294 | goto error_unlock; | ||
295 | 328 | ||
296 | // TODO: Trim excess pages | 329 | // TODO: Trim excess pages |
297 | 330 | ||
@@ -743,7 +776,7 @@ success: | |||
743 | ti = afs_iget(dir->i_sb, key, &cookie->fids[i], | 776 | ti = afs_iget(dir->i_sb, key, &cookie->fids[i], |
744 | &cookie->statuses[i], | 777 | &cookie->statuses[i], |
745 | &cookie->callbacks[i], | 778 | &cookie->callbacks[i], |
746 | cbi); | 779 | cbi, dvnode); |
747 | if (i == 0) { | 780 | if (i == 0) { |
748 | inode = ti; | 781 | inode = ti; |
749 | } else { | 782 | } else { |
@@ -875,8 +908,14 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, | |||
875 | (void *)(unsigned long)dvnode->status.data_version; | 908 | (void *)(unsigned long)dvnode->status.data_version; |
876 | } | 909 | } |
877 | d = d_splice_alias(inode, dentry); | 910 | d = d_splice_alias(inode, dentry); |
878 | if (!IS_ERR_OR_NULL(d)) | 911 | if (!IS_ERR_OR_NULL(d)) { |
879 | d->d_fsdata = dentry->d_fsdata; | 912 | d->d_fsdata = dentry->d_fsdata; |
913 | trace_afs_lookup(dvnode, &d->d_name, | ||
914 | inode ? AFS_FS_I(inode) : NULL); | ||
915 | } else { | ||
916 | trace_afs_lookup(dvnode, &dentry->d_name, | ||
917 | inode ? AFS_FS_I(inode) : NULL); | ||
918 | } | ||
880 | return d; | 919 | return d; |
881 | } | 920 | } |
882 | 921 | ||
@@ -1053,6 +1092,16 @@ zap: | |||
1053 | } | 1092 | } |
1054 | 1093 | ||
1055 | /* | 1094 | /* |
1095 | * Clean up sillyrename files on dentry removal. | ||
1096 | */ | ||
1097 | static void afs_d_iput(struct dentry *dentry, struct inode *inode) | ||
1098 | { | ||
1099 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) | ||
1100 | afs_silly_iput(dentry, inode); | ||
1101 | iput(inode); | ||
1102 | } | ||
1103 | |||
1104 | /* | ||
1056 | * handle dentry release | 1105 | * handle dentry release |
1057 | */ | 1106 | */ |
1058 | void afs_d_release(struct dentry *dentry) | 1107 | void afs_d_release(struct dentry *dentry) |
@@ -1076,7 +1125,7 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc, | |||
1076 | return; | 1125 | return; |
1077 | 1126 | ||
1078 | inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key, | 1127 | inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key, |
1079 | newfid, newstatus, newcb, fc->cbi); | 1128 | newfid, newstatus, newcb, fc->cbi, fc->vnode); |
1080 | if (IS_ERR(inode)) { | 1129 | if (IS_ERR(inode)) { |
1081 | /* ENOMEM or EINTR at a really inconvenient time - just abandon | 1130 | /* ENOMEM or EINTR at a really inconvenient time - just abandon |
1082 | * the new directory on the server. | 1131 | * the new directory on the server. |
@@ -1194,6 +1243,12 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1194 | goto error_key; | 1243 | goto error_key; |
1195 | } | 1244 | } |
1196 | 1245 | ||
1246 | if (vnode) { | ||
1247 | ret = down_write_killable(&vnode->rmdir_lock); | ||
1248 | if (ret < 0) | ||
1249 | goto error_key; | ||
1250 | } | ||
1251 | |||
1197 | ret = -ERESTARTSYS; | 1252 | ret = -ERESTARTSYS; |
1198 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { | 1253 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { |
1199 | while (afs_select_fileserver(&fc)) { | 1254 | while (afs_select_fileserver(&fc)) { |
@@ -1212,6 +1267,8 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1212 | } | 1267 | } |
1213 | } | 1268 | } |
1214 | 1269 | ||
1270 | if (vnode) | ||
1271 | up_write(&vnode->rmdir_lock); | ||
1215 | error_key: | 1272 | error_key: |
1216 | key_put(key); | 1273 | key_put(key); |
1217 | error: | 1274 | error: |
@@ -1228,9 +1285,9 @@ error: | |||
1228 | * However, if we didn't have a callback promise outstanding, or it was | 1285 | * However, if we didn't have a callback promise outstanding, or it was |
1229 | * outstanding on a different server, then it won't break it either... | 1286 | * outstanding on a different server, then it won't break it either... |
1230 | */ | 1287 | */ |
1231 | static int afs_dir_remove_link(struct dentry *dentry, struct key *key, | 1288 | int afs_dir_remove_link(struct dentry *dentry, struct key *key, |
1232 | unsigned long d_version_before, | 1289 | unsigned long d_version_before, |
1233 | unsigned long d_version_after) | 1290 | unsigned long d_version_after) |
1234 | { | 1291 | { |
1235 | bool dir_valid; | 1292 | bool dir_valid; |
1236 | int ret = 0; | 1293 | int ret = 0; |
@@ -1277,6 +1334,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) | |||
1277 | struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL; | 1334 | struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL; |
1278 | struct key *key; | 1335 | struct key *key; |
1279 | unsigned long d_version = (unsigned long)dentry->d_fsdata; | 1336 | unsigned long d_version = (unsigned long)dentry->d_fsdata; |
1337 | bool need_rehash = false; | ||
1280 | u64 data_version = dvnode->status.data_version; | 1338 | u64 data_version = dvnode->status.data_version; |
1281 | int ret; | 1339 | int ret; |
1282 | 1340 | ||
@@ -1300,6 +1358,21 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) | |||
1300 | goto error_key; | 1358 | goto error_key; |
1301 | } | 1359 | } |
1302 | 1360 | ||
1361 | spin_lock(&dentry->d_lock); | ||
1362 | if (vnode && d_count(dentry) > 1) { | ||
1363 | spin_unlock(&dentry->d_lock); | ||
1364 | /* Start asynchronous writeout of the inode */ | ||
1365 | write_inode_now(d_inode(dentry), 0); | ||
1366 | ret = afs_sillyrename(dvnode, vnode, dentry, key); | ||
1367 | goto error_key; | ||
1368 | } | ||
1369 | if (!d_unhashed(dentry)) { | ||
1370 | /* Prevent a race with RCU lookup. */ | ||
1371 | __d_drop(dentry); | ||
1372 | need_rehash = true; | ||
1373 | } | ||
1374 | spin_unlock(&dentry->d_lock); | ||
1375 | |||
1303 | ret = -ERESTARTSYS; | 1376 | ret = -ERESTARTSYS; |
1304 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { | 1377 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { |
1305 | while (afs_select_fileserver(&fc)) { | 1378 | while (afs_select_fileserver(&fc)) { |
@@ -1331,6 +1404,9 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry) | |||
1331 | afs_edit_dir_for_unlink); | 1404 | afs_edit_dir_for_unlink); |
1332 | } | 1405 | } |
1333 | 1406 | ||
1407 | if (need_rehash && ret < 0 && ret != -ENOENT) | ||
1408 | d_rehash(dentry); | ||
1409 | |||
1334 | error_key: | 1410 | error_key: |
1335 | key_put(key); | 1411 | key_put(key); |
1336 | error: | 1412 | error: |
@@ -1551,6 +1627,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1551 | { | 1627 | { |
1552 | struct afs_fs_cursor fc; | 1628 | struct afs_fs_cursor fc; |
1553 | struct afs_vnode *orig_dvnode, *new_dvnode, *vnode; | 1629 | struct afs_vnode *orig_dvnode, *new_dvnode, *vnode; |
1630 | struct dentry *tmp = NULL, *rehash = NULL; | ||
1631 | struct inode *new_inode; | ||
1554 | struct key *key; | 1632 | struct key *key; |
1555 | u64 orig_data_version, new_data_version; | 1633 | u64 orig_data_version, new_data_version; |
1556 | bool new_negative = d_is_negative(new_dentry); | 1634 | bool new_negative = d_is_negative(new_dentry); |
@@ -1559,6 +1637,10 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1559 | if (flags) | 1637 | if (flags) |
1560 | return -EINVAL; | 1638 | return -EINVAL; |
1561 | 1639 | ||
1640 | /* Don't allow silly-rename files be moved around. */ | ||
1641 | if (old_dentry->d_flags & DCACHE_NFSFS_RENAMED) | ||
1642 | return -EINVAL; | ||
1643 | |||
1562 | vnode = AFS_FS_I(d_inode(old_dentry)); | 1644 | vnode = AFS_FS_I(d_inode(old_dentry)); |
1563 | orig_dvnode = AFS_FS_I(old_dir); | 1645 | orig_dvnode = AFS_FS_I(old_dir); |
1564 | new_dvnode = AFS_FS_I(new_dir); | 1646 | new_dvnode = AFS_FS_I(new_dir); |
@@ -1577,12 +1659,48 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1577 | goto error; | 1659 | goto error; |
1578 | } | 1660 | } |
1579 | 1661 | ||
1662 | /* For non-directories, check whether the target is busy and if so, | ||
1663 | * make a copy of the dentry and then do a silly-rename. If the | ||
1664 | * silly-rename succeeds, the copied dentry is hashed and becomes the | ||
1665 | * new target. | ||
1666 | */ | ||
1667 | if (d_is_positive(new_dentry) && !d_is_dir(new_dentry)) { | ||
1668 | /* To prevent any new references to the target during the | ||
1669 | * rename, we unhash the dentry in advance. | ||
1670 | */ | ||
1671 | if (!d_unhashed(new_dentry)) { | ||
1672 | d_drop(new_dentry); | ||
1673 | rehash = new_dentry; | ||
1674 | } | ||
1675 | |||
1676 | if (d_count(new_dentry) > 2) { | ||
1677 | /* copy the target dentry's name */ | ||
1678 | ret = -ENOMEM; | ||
1679 | tmp = d_alloc(new_dentry->d_parent, | ||
1680 | &new_dentry->d_name); | ||
1681 | if (!tmp) | ||
1682 | goto error_rehash; | ||
1683 | |||
1684 | ret = afs_sillyrename(new_dvnode, | ||
1685 | AFS_FS_I(d_inode(new_dentry)), | ||
1686 | new_dentry, key); | ||
1687 | if (ret) | ||
1688 | goto error_rehash; | ||
1689 | |||
1690 | new_dentry = tmp; | ||
1691 | rehash = NULL; | ||
1692 | new_negative = true; | ||
1693 | orig_data_version = orig_dvnode->status.data_version; | ||
1694 | new_data_version = new_dvnode->status.data_version; | ||
1695 | } | ||
1696 | } | ||
1697 | |||
1580 | ret = -ERESTARTSYS; | 1698 | ret = -ERESTARTSYS; |
1581 | if (afs_begin_vnode_operation(&fc, orig_dvnode, key)) { | 1699 | if (afs_begin_vnode_operation(&fc, orig_dvnode, key)) { |
1582 | if (orig_dvnode != new_dvnode) { | 1700 | if (orig_dvnode != new_dvnode) { |
1583 | if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) { | 1701 | if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) { |
1584 | afs_end_vnode_operation(&fc); | 1702 | afs_end_vnode_operation(&fc); |
1585 | goto error_key; | 1703 | goto error_rehash; |
1586 | } | 1704 | } |
1587 | } | 1705 | } |
1588 | while (afs_select_fileserver(&fc)) { | 1706 | while (afs_select_fileserver(&fc)) { |
@@ -1599,25 +1717,42 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1599 | mutex_unlock(&new_dvnode->io_lock); | 1717 | mutex_unlock(&new_dvnode->io_lock); |
1600 | ret = afs_end_vnode_operation(&fc); | 1718 | ret = afs_end_vnode_operation(&fc); |
1601 | if (ret < 0) | 1719 | if (ret < 0) |
1602 | goto error_key; | 1720 | goto error_rehash; |
1603 | } | 1721 | } |
1604 | 1722 | ||
1605 | if (ret == 0) { | 1723 | if (ret == 0) { |
1724 | if (rehash) | ||
1725 | d_rehash(rehash); | ||
1606 | if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags)) | 1726 | if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags)) |
1607 | afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name, | 1727 | afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name, |
1608 | afs_edit_dir_for_rename); | 1728 | afs_edit_dir_for_rename_0); |
1609 | 1729 | ||
1610 | if (!new_negative && | 1730 | if (!new_negative && |
1611 | test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) | 1731 | test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) |
1612 | afs_edit_dir_remove(new_dvnode, &new_dentry->d_name, | 1732 | afs_edit_dir_remove(new_dvnode, &new_dentry->d_name, |
1613 | afs_edit_dir_for_rename); | 1733 | afs_edit_dir_for_rename_1); |
1614 | 1734 | ||
1615 | if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) | 1735 | if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) |
1616 | afs_edit_dir_add(new_dvnode, &new_dentry->d_name, | 1736 | afs_edit_dir_add(new_dvnode, &new_dentry->d_name, |
1617 | &vnode->fid, afs_edit_dir_for_rename); | 1737 | &vnode->fid, afs_edit_dir_for_rename_2); |
1738 | |||
1739 | new_inode = d_inode(new_dentry); | ||
1740 | if (new_inode) { | ||
1741 | spin_lock(&new_inode->i_lock); | ||
1742 | if (new_inode->i_nlink > 0) | ||
1743 | drop_nlink(new_inode); | ||
1744 | spin_unlock(&new_inode->i_lock); | ||
1745 | } | ||
1746 | d_move(old_dentry, new_dentry); | ||
1747 | goto error_tmp; | ||
1618 | } | 1748 | } |
1619 | 1749 | ||
1620 | error_key: | 1750 | error_rehash: |
1751 | if (rehash) | ||
1752 | d_rehash(rehash); | ||
1753 | error_tmp: | ||
1754 | if (tmp) | ||
1755 | dput(tmp); | ||
1621 | key_put(key); | 1756 | key_put(key); |
1622 | error: | 1757 | error: |
1623 | _leave(" = %d", ret); | 1758 | _leave(" = %d", ret); |
diff --git a/fs/afs/dir_silly.c b/fs/afs/dir_silly.c new file mode 100644 index 000000000000..f6f89fdab6b2 --- /dev/null +++ b/fs/afs/dir_silly.c | |||
@@ -0,0 +1,239 @@ | |||
1 | /* AFS silly rename handling | ||
2 | * | ||
3 | * Copyright (C) 2019 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * - Derived from NFS's sillyrename. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public Licence | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the Licence, or (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/fs.h> | ||
15 | #include <linux/namei.h> | ||
16 | #include <linux/fsnotify.h> | ||
17 | #include "internal.h" | ||
18 | |||
19 | /* | ||
20 | * Actually perform the silly rename step. | ||
21 | */ | ||
22 | static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode, | ||
23 | struct dentry *old, struct dentry *new, | ||
24 | struct key *key) | ||
25 | { | ||
26 | struct afs_fs_cursor fc; | ||
27 | u64 dir_data_version = dvnode->status.data_version; | ||
28 | int ret = -ERESTARTSYS; | ||
29 | |||
30 | _enter("%pd,%pd", old, new); | ||
31 | |||
32 | trace_afs_silly_rename(vnode, false); | ||
33 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { | ||
34 | while (afs_select_fileserver(&fc)) { | ||
35 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); | ||
36 | afs_fs_rename(&fc, old->d_name.name, | ||
37 | dvnode, new->d_name.name, | ||
38 | dir_data_version, dir_data_version); | ||
39 | } | ||
40 | |||
41 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break); | ||
42 | ret = afs_end_vnode_operation(&fc); | ||
43 | } | ||
44 | |||
45 | if (ret == 0) { | ||
46 | spin_lock(&old->d_lock); | ||
47 | old->d_flags |= DCACHE_NFSFS_RENAMED; | ||
48 | spin_unlock(&old->d_lock); | ||
49 | if (dvnode->silly_key != key) { | ||
50 | key_put(dvnode->silly_key); | ||
51 | dvnode->silly_key = key_get(key); | ||
52 | } | ||
53 | |||
54 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) | ||
55 | afs_edit_dir_remove(dvnode, &old->d_name, | ||
56 | afs_edit_dir_for_silly_0); | ||
57 | if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) | ||
58 | afs_edit_dir_add(dvnode, &new->d_name, | ||
59 | &vnode->fid, afs_edit_dir_for_silly_1); | ||
60 | |||
61 | /* vfs_unlink and the like do not issue this when a file is | ||
62 | * sillyrenamed, so do it here. | ||
63 | */ | ||
64 | fsnotify_nameremove(old, 0); | ||
65 | } | ||
66 | |||
67 | _leave(" = %d", ret); | ||
68 | return ret; | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * afs_sillyrename - Perform a silly-rename of a dentry | ||
73 | * | ||
74 | * AFS is stateless and the server doesn't know when the client is holding a | ||
75 | * file open. To prevent application problems when a file is unlinked while | ||
76 | * it's still open, the client performs a "silly-rename". That is, it renames | ||
77 | * the file to a hidden file in the same directory, and only performs the | ||
78 | * unlink once the last reference to it is put. | ||
79 | * | ||
80 | * The final cleanup is done during dentry_iput. | ||
81 | */ | ||
82 | int afs_sillyrename(struct afs_vnode *dvnode, struct afs_vnode *vnode, | ||
83 | struct dentry *dentry, struct key *key) | ||
84 | { | ||
85 | static unsigned int sillycounter; | ||
86 | struct dentry *sdentry = NULL; | ||
87 | unsigned char silly[16]; | ||
88 | int ret = -EBUSY; | ||
89 | |||
90 | _enter(""); | ||
91 | |||
92 | /* We don't allow a dentry to be silly-renamed twice. */ | ||
93 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) | ||
94 | return -EBUSY; | ||
95 | |||
96 | sdentry = NULL; | ||
97 | do { | ||
98 | int slen; | ||
99 | |||
100 | dput(sdentry); | ||
101 | sillycounter++; | ||
102 | |||
103 | /* Create a silly name. Note that the ".__afs" prefix is | ||
104 | * understood by the salvager and must not be changed. | ||
105 | */ | ||
106 | slen = scnprintf(silly, sizeof(silly), ".__afs%04X", sillycounter); | ||
107 | sdentry = lookup_one_len(silly, dentry->d_parent, slen); | ||
108 | |||
109 | /* N.B. Better to return EBUSY here ... it could be dangerous | ||
110 | * to delete the file while it's in use. | ||
111 | */ | ||
112 | if (IS_ERR(sdentry)) | ||
113 | goto out; | ||
114 | } while (!d_is_negative(sdentry)); | ||
115 | |||
116 | ihold(&vnode->vfs_inode); | ||
117 | |||
118 | ret = afs_do_silly_rename(dvnode, vnode, dentry, sdentry, key); | ||
119 | switch (ret) { | ||
120 | case 0: | ||
121 | /* The rename succeeded. */ | ||
122 | d_move(dentry, sdentry); | ||
123 | break; | ||
124 | case -ERESTARTSYS: | ||
125 | /* The result of the rename is unknown. Play it safe by forcing | ||
126 | * a new lookup. | ||
127 | */ | ||
128 | d_drop(dentry); | ||
129 | d_drop(sdentry); | ||
130 | } | ||
131 | |||
132 | iput(&vnode->vfs_inode); | ||
133 | dput(sdentry); | ||
134 | out: | ||
135 | _leave(" = %d", ret); | ||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * Tell the server to remove a sillyrename file. | ||
141 | */ | ||
142 | static int afs_do_silly_unlink(struct afs_vnode *dvnode, struct afs_vnode *vnode, | ||
143 | struct dentry *dentry, struct key *key) | ||
144 | { | ||
145 | struct afs_fs_cursor fc; | ||
146 | u64 dir_data_version = dvnode->status.data_version; | ||
147 | int ret = -ERESTARTSYS; | ||
148 | |||
149 | _enter(""); | ||
150 | |||
151 | trace_afs_silly_rename(vnode, true); | ||
152 | if (afs_begin_vnode_operation(&fc, dvnode, key)) { | ||
153 | while (afs_select_fileserver(&fc)) { | ||
154 | fc.cb_break = afs_calc_vnode_cb_break(dvnode); | ||
155 | |||
156 | if (test_bit(AFS_SERVER_FL_IS_YFS, &fc.cbi->server->flags) && | ||
157 | !test_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags)) { | ||
158 | yfs_fs_remove_file2(&fc, vnode, dentry->d_name.name, | ||
159 | dir_data_version); | ||
160 | if (fc.ac.error != -ECONNABORTED || | ||
161 | fc.ac.abort_code != RXGEN_OPCODE) | ||
162 | continue; | ||
163 | set_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags); | ||
164 | } | ||
165 | |||
166 | afs_fs_remove(&fc, vnode, dentry->d_name.name, false, | ||
167 | dir_data_version); | ||
168 | } | ||
169 | |||
170 | afs_vnode_commit_status(&fc, dvnode, fc.cb_break); | ||
171 | ret = afs_end_vnode_operation(&fc); | ||
172 | if (ret == 0) { | ||
173 | drop_nlink(&vnode->vfs_inode); | ||
174 | if (vnode->vfs_inode.i_nlink == 0) { | ||
175 | set_bit(AFS_VNODE_DELETED, &vnode->flags); | ||
176 | clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); | ||
177 | } | ||
178 | } | ||
179 | if (ret == 0 && | ||
180 | test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) | ||
181 | afs_edit_dir_remove(dvnode, &dentry->d_name, | ||
182 | afs_edit_dir_for_unlink); | ||
183 | } | ||
184 | |||
185 | _leave(" = %d", ret); | ||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * Remove sillyrename file on iput. | ||
191 | */ | ||
192 | int afs_silly_iput(struct dentry *dentry, struct inode *inode) | ||
193 | { | ||
194 | struct afs_vnode *dvnode = AFS_FS_I(d_inode(dentry->d_parent)); | ||
195 | struct afs_vnode *vnode = AFS_FS_I(inode); | ||
196 | struct dentry *alias; | ||
197 | int ret; | ||
198 | |||
199 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); | ||
200 | |||
201 | _enter("%p{%pd},%llx", dentry, dentry, vnode->fid.vnode); | ||
202 | |||
203 | down_read(&dvnode->rmdir_lock); | ||
204 | |||
205 | alias = d_alloc_parallel(dentry->d_parent, &dentry->d_name, &wq); | ||
206 | if (IS_ERR(alias)) { | ||
207 | up_read(&dvnode->rmdir_lock); | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | if (!d_in_lookup(alias)) { | ||
212 | /* We raced with lookup... See if we need to transfer the | ||
213 | * sillyrename information to the aliased dentry. | ||
214 | */ | ||
215 | ret = 0; | ||
216 | spin_lock(&alias->d_lock); | ||
217 | if (d_really_is_positive(alias) && | ||
218 | !(alias->d_flags & DCACHE_NFSFS_RENAMED)) { | ||
219 | alias->d_flags |= DCACHE_NFSFS_RENAMED; | ||
220 | ret = 1; | ||
221 | } | ||
222 | spin_unlock(&alias->d_lock); | ||
223 | up_read(&dvnode->rmdir_lock); | ||
224 | dput(alias); | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | /* Stop lock-release from complaining. */ | ||
229 | spin_lock(&vnode->lock); | ||
230 | vnode->lock_state = AFS_VNODE_LOCK_DELETED; | ||
231 | trace_afs_flock_ev(vnode, NULL, afs_flock_silly_delete, 0); | ||
232 | spin_unlock(&vnode->lock); | ||
233 | |||
234 | afs_do_silly_unlink(dvnode, vnode, dentry, dvnode->silly_key); | ||
235 | up_read(&dvnode->rmdir_lock); | ||
236 | d_lookup_done(alias); | ||
237 | dput(alias); | ||
238 | return 1; | ||
239 | } | ||
diff --git a/fs/afs/flock.c b/fs/afs/flock.c index 6a0174258382..adc88eff7849 100644 --- a/fs/afs/flock.c +++ b/fs/afs/flock.c | |||
@@ -13,9 +13,11 @@ | |||
13 | 13 | ||
14 | #define AFS_LOCK_GRANTED 0 | 14 | #define AFS_LOCK_GRANTED 0 |
15 | #define AFS_LOCK_PENDING 1 | 15 | #define AFS_LOCK_PENDING 1 |
16 | #define AFS_LOCK_YOUR_TRY 2 | ||
16 | 17 | ||
17 | struct workqueue_struct *afs_lock_manager; | 18 | struct workqueue_struct *afs_lock_manager; |
18 | 19 | ||
20 | static void afs_next_locker(struct afs_vnode *vnode, int error); | ||
19 | static void afs_fl_copy_lock(struct file_lock *new, struct file_lock *fl); | 21 | static void afs_fl_copy_lock(struct file_lock *new, struct file_lock *fl); |
20 | static void afs_fl_release_private(struct file_lock *fl); | 22 | static void afs_fl_release_private(struct file_lock *fl); |
21 | 23 | ||
@@ -24,6 +26,14 @@ static const struct file_lock_operations afs_lock_ops = { | |||
24 | .fl_release_private = afs_fl_release_private, | 26 | .fl_release_private = afs_fl_release_private, |
25 | }; | 27 | }; |
26 | 28 | ||
29 | static inline void afs_set_lock_state(struct afs_vnode *vnode, enum afs_lock_state state) | ||
30 | { | ||
31 | _debug("STATE %u -> %u", vnode->lock_state, state); | ||
32 | vnode->lock_state = state; | ||
33 | } | ||
34 | |||
35 | static atomic_t afs_file_lock_debug_id; | ||
36 | |||
27 | /* | 37 | /* |
28 | * if the callback is broken on this vnode, then the lock may now be available | 38 | * if the callback is broken on this vnode, then the lock may now be available |
29 | */ | 39 | */ |
@@ -31,7 +41,14 @@ void afs_lock_may_be_available(struct afs_vnode *vnode) | |||
31 | { | 41 | { |
32 | _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); | 42 | _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); |
33 | 43 | ||
34 | queue_delayed_work(afs_lock_manager, &vnode->lock_work, 0); | 44 | if (vnode->lock_state != AFS_VNODE_LOCK_WAITING_FOR_CB) |
45 | return; | ||
46 | |||
47 | spin_lock(&vnode->lock); | ||
48 | if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB) | ||
49 | afs_next_locker(vnode, 0); | ||
50 | trace_afs_flock_ev(vnode, NULL, afs_flock_callback_break, 0); | ||
51 | spin_unlock(&vnode->lock); | ||
35 | } | 52 | } |
36 | 53 | ||
37 | /* | 54 | /* |
@@ -40,8 +57,35 @@ void afs_lock_may_be_available(struct afs_vnode *vnode) | |||
40 | */ | 57 | */ |
41 | static void afs_schedule_lock_extension(struct afs_vnode *vnode) | 58 | static void afs_schedule_lock_extension(struct afs_vnode *vnode) |
42 | { | 59 | { |
43 | queue_delayed_work(afs_lock_manager, &vnode->lock_work, | 60 | ktime_t expires_at, now, duration; |
44 | AFS_LOCKWAIT * HZ / 2); | 61 | u64 duration_j; |
62 | |||
63 | expires_at = ktime_add_ms(vnode->locked_at, AFS_LOCKWAIT * 1000 / 2); | ||
64 | now = ktime_get_real(); | ||
65 | duration = ktime_sub(expires_at, now); | ||
66 | if (duration <= 0) | ||
67 | duration_j = 0; | ||
68 | else | ||
69 | duration_j = nsecs_to_jiffies(ktime_to_ns(duration)); | ||
70 | |||
71 | queue_delayed_work(afs_lock_manager, &vnode->lock_work, duration_j); | ||
72 | } | ||
73 | |||
74 | /* | ||
75 | * In the case of successful completion of a lock operation, record the time | ||
76 | * the reply appeared and start the lock extension timer. | ||
77 | */ | ||
78 | void afs_lock_op_done(struct afs_call *call) | ||
79 | { | ||
80 | struct afs_vnode *vnode = call->reply[0]; | ||
81 | |||
82 | if (call->error == 0) { | ||
83 | spin_lock(&vnode->lock); | ||
84 | trace_afs_flock_ev(vnode, NULL, afs_flock_timestamp, 0); | ||
85 | vnode->locked_at = call->reply_time; | ||
86 | afs_schedule_lock_extension(vnode); | ||
87 | spin_unlock(&vnode->lock); | ||
88 | } | ||
45 | } | 89 | } |
46 | 90 | ||
47 | /* | 91 | /* |
@@ -49,22 +93,90 @@ static void afs_schedule_lock_extension(struct afs_vnode *vnode) | |||
49 | * first lock in the queue is itself a readlock) | 93 | * first lock in the queue is itself a readlock) |
50 | * - the caller must hold the vnode lock | 94 | * - the caller must hold the vnode lock |
51 | */ | 95 | */ |
52 | static void afs_grant_locks(struct afs_vnode *vnode, struct file_lock *fl) | 96 | static void afs_grant_locks(struct afs_vnode *vnode) |
53 | { | 97 | { |
54 | struct file_lock *p, *_p; | 98 | struct file_lock *p, *_p; |
99 | bool exclusive = (vnode->lock_type == AFS_LOCK_WRITE); | ||
55 | 100 | ||
56 | list_move_tail(&fl->fl_u.afs.link, &vnode->granted_locks); | 101 | list_for_each_entry_safe(p, _p, &vnode->pending_locks, fl_u.afs.link) { |
57 | if (fl->fl_type == F_RDLCK) { | 102 | if (!exclusive && p->fl_type == F_WRLCK) |
58 | list_for_each_entry_safe(p, _p, &vnode->pending_locks, | 103 | continue; |
59 | fl_u.afs.link) { | 104 | |
60 | if (p->fl_type == F_RDLCK) { | 105 | list_move_tail(&p->fl_u.afs.link, &vnode->granted_locks); |
61 | p->fl_u.afs.state = AFS_LOCK_GRANTED; | 106 | p->fl_u.afs.state = AFS_LOCK_GRANTED; |
62 | list_move_tail(&p->fl_u.afs.link, | 107 | trace_afs_flock_op(vnode, p, afs_flock_op_grant); |
63 | &vnode->granted_locks); | 108 | wake_up(&p->fl_wait); |
64 | wake_up(&p->fl_wait); | 109 | } |
65 | } | 110 | } |
111 | |||
112 | /* | ||
113 | * If an error is specified, reject every pending lock that matches the | ||
114 | * authentication and type of the lock we failed to get. If there are any | ||
115 | * remaining lockers, try to wake up one of them to have a go. | ||
116 | */ | ||
117 | static void afs_next_locker(struct afs_vnode *vnode, int error) | ||
118 | { | ||
119 | struct file_lock *p, *_p, *next = NULL; | ||
120 | struct key *key = vnode->lock_key; | ||
121 | unsigned int fl_type = F_RDLCK; | ||
122 | |||
123 | _enter(""); | ||
124 | |||
125 | if (vnode->lock_type == AFS_LOCK_WRITE) | ||
126 | fl_type = F_WRLCK; | ||
127 | |||
128 | list_for_each_entry_safe(p, _p, &vnode->pending_locks, fl_u.afs.link) { | ||
129 | if (error && | ||
130 | p->fl_type == fl_type && | ||
131 | afs_file_key(p->fl_file) == key) { | ||
132 | list_del_init(&p->fl_u.afs.link); | ||
133 | p->fl_u.afs.state = error; | ||
134 | wake_up(&p->fl_wait); | ||
66 | } | 135 | } |
136 | |||
137 | /* Select the next locker to hand off to. */ | ||
138 | if (next && | ||
139 | (next->fl_type == F_WRLCK || p->fl_type == F_RDLCK)) | ||
140 | continue; | ||
141 | next = p; | ||
67 | } | 142 | } |
143 | |||
144 | vnode->lock_key = NULL; | ||
145 | key_put(key); | ||
146 | |||
147 | if (next) { | ||
148 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_SETTING); | ||
149 | next->fl_u.afs.state = AFS_LOCK_YOUR_TRY; | ||
150 | trace_afs_flock_op(vnode, next, afs_flock_op_wake); | ||
151 | wake_up(&next->fl_wait); | ||
152 | } else { | ||
153 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_NONE); | ||
154 | trace_afs_flock_ev(vnode, NULL, afs_flock_no_lockers, 0); | ||
155 | } | ||
156 | |||
157 | _leave(""); | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Kill off all waiters in the the pending lock queue due to the vnode being | ||
162 | * deleted. | ||
163 | */ | ||
164 | static void afs_kill_lockers_enoent(struct afs_vnode *vnode) | ||
165 | { | ||
166 | struct file_lock *p; | ||
167 | |||
168 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_DELETED); | ||
169 | |||
170 | while (!list_empty(&vnode->pending_locks)) { | ||
171 | p = list_entry(vnode->pending_locks.next, | ||
172 | struct file_lock, fl_u.afs.link); | ||
173 | list_del_init(&p->fl_u.afs.link); | ||
174 | p->fl_u.afs.state = -ENOENT; | ||
175 | wake_up(&p->fl_wait); | ||
176 | } | ||
177 | |||
178 | key_put(vnode->lock_key); | ||
179 | vnode->lock_key = NULL; | ||
68 | } | 180 | } |
69 | 181 | ||
70 | /* | 182 | /* |
@@ -170,8 +282,6 @@ void afs_lock_work(struct work_struct *work) | |||
170 | { | 282 | { |
171 | struct afs_vnode *vnode = | 283 | struct afs_vnode *vnode = |
172 | container_of(work, struct afs_vnode, lock_work.work); | 284 | container_of(work, struct afs_vnode, lock_work.work); |
173 | struct file_lock *fl, *next; | ||
174 | afs_lock_type_t type; | ||
175 | struct key *key; | 285 | struct key *key; |
176 | int ret; | 286 | int ret; |
177 | 287 | ||
@@ -183,35 +293,28 @@ again: | |||
183 | _debug("wstate %u for %p", vnode->lock_state, vnode); | 293 | _debug("wstate %u for %p", vnode->lock_state, vnode); |
184 | switch (vnode->lock_state) { | 294 | switch (vnode->lock_state) { |
185 | case AFS_VNODE_LOCK_NEED_UNLOCK: | 295 | case AFS_VNODE_LOCK_NEED_UNLOCK: |
186 | _debug("unlock"); | 296 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_UNLOCKING); |
187 | vnode->lock_state = AFS_VNODE_LOCK_UNLOCKING; | 297 | trace_afs_flock_ev(vnode, NULL, afs_flock_work_unlocking, 0); |
188 | spin_unlock(&vnode->lock); | 298 | spin_unlock(&vnode->lock); |
189 | 299 | ||
190 | /* attempt to release the server lock; if it fails, we just | 300 | /* attempt to release the server lock; if it fails, we just |
191 | * wait 5 minutes and it'll expire anyway */ | 301 | * wait 5 minutes and it'll expire anyway */ |
192 | ret = afs_release_lock(vnode, vnode->lock_key); | 302 | ret = afs_release_lock(vnode, vnode->lock_key); |
193 | if (ret < 0) | 303 | if (ret < 0 && vnode->lock_state != AFS_VNODE_LOCK_DELETED) { |
304 | trace_afs_flock_ev(vnode, NULL, afs_flock_release_fail, | ||
305 | ret); | ||
194 | printk(KERN_WARNING "AFS:" | 306 | printk(KERN_WARNING "AFS:" |
195 | " Failed to release lock on {%llx:%llx} error %d\n", | 307 | " Failed to release lock on {%llx:%llx} error %d\n", |
196 | vnode->fid.vid, vnode->fid.vnode, ret); | 308 | vnode->fid.vid, vnode->fid.vnode, ret); |
197 | |||
198 | spin_lock(&vnode->lock); | ||
199 | key_put(vnode->lock_key); | ||
200 | vnode->lock_key = NULL; | ||
201 | vnode->lock_state = AFS_VNODE_LOCK_NONE; | ||
202 | |||
203 | if (list_empty(&vnode->pending_locks)) { | ||
204 | spin_unlock(&vnode->lock); | ||
205 | return; | ||
206 | } | 309 | } |
207 | 310 | ||
208 | /* The new front of the queue now owns the state variables. */ | 311 | spin_lock(&vnode->lock); |
209 | next = list_entry(vnode->pending_locks.next, | 312 | if (ret == -ENOENT) |
210 | struct file_lock, fl_u.afs.link); | 313 | afs_kill_lockers_enoent(vnode); |
211 | vnode->lock_key = key_get(afs_file_key(next->fl_file)); | 314 | else |
212 | vnode->lock_type = (next->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; | 315 | afs_next_locker(vnode, 0); |
213 | vnode->lock_state = AFS_VNODE_LOCK_WAITING_FOR_CB; | 316 | spin_unlock(&vnode->lock); |
214 | goto again; | 317 | return; |
215 | 318 | ||
216 | /* If we've already got a lock, then it must be time to extend that | 319 | /* If we've already got a lock, then it must be time to extend that |
217 | * lock as AFS locks time out after 5 minutes. | 320 | * lock as AFS locks time out after 5 minutes. |
@@ -222,86 +325,55 @@ again: | |||
222 | ASSERT(!list_empty(&vnode->granted_locks)); | 325 | ASSERT(!list_empty(&vnode->granted_locks)); |
223 | 326 | ||
224 | key = key_get(vnode->lock_key); | 327 | key = key_get(vnode->lock_key); |
225 | vnode->lock_state = AFS_VNODE_LOCK_EXTENDING; | 328 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_EXTENDING); |
329 | trace_afs_flock_ev(vnode, NULL, afs_flock_work_extending, 0); | ||
226 | spin_unlock(&vnode->lock); | 330 | spin_unlock(&vnode->lock); |
227 | 331 | ||
228 | ret = afs_extend_lock(vnode, key); /* RPC */ | 332 | ret = afs_extend_lock(vnode, key); /* RPC */ |
229 | key_put(key); | 333 | key_put(key); |
230 | 334 | ||
231 | if (ret < 0) | 335 | if (ret < 0) { |
336 | trace_afs_flock_ev(vnode, NULL, afs_flock_extend_fail, | ||
337 | ret); | ||
232 | pr_warning("AFS: Failed to extend lock on {%llx:%llx} error %d\n", | 338 | pr_warning("AFS: Failed to extend lock on {%llx:%llx} error %d\n", |
233 | vnode->fid.vid, vnode->fid.vnode, ret); | 339 | vnode->fid.vid, vnode->fid.vnode, ret); |
340 | } | ||
234 | 341 | ||
235 | spin_lock(&vnode->lock); | 342 | spin_lock(&vnode->lock); |
236 | 343 | ||
344 | if (ret == -ENOENT) { | ||
345 | afs_kill_lockers_enoent(vnode); | ||
346 | spin_unlock(&vnode->lock); | ||
347 | return; | ||
348 | } | ||
349 | |||
237 | if (vnode->lock_state != AFS_VNODE_LOCK_EXTENDING) | 350 | if (vnode->lock_state != AFS_VNODE_LOCK_EXTENDING) |
238 | goto again; | 351 | goto again; |
239 | vnode->lock_state = AFS_VNODE_LOCK_GRANTED; | 352 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_GRANTED); |
240 | 353 | ||
241 | if (ret == 0) | 354 | if (ret != 0) |
242 | afs_schedule_lock_extension(vnode); | ||
243 | else | ||
244 | queue_delayed_work(afs_lock_manager, &vnode->lock_work, | 355 | queue_delayed_work(afs_lock_manager, &vnode->lock_work, |
245 | HZ * 10); | 356 | HZ * 10); |
246 | spin_unlock(&vnode->lock); | 357 | spin_unlock(&vnode->lock); |
247 | _leave(" [ext]"); | 358 | _leave(" [ext]"); |
248 | return; | 359 | return; |
249 | 360 | ||
250 | /* If we don't have a granted lock, then we must've been called | 361 | /* If we're waiting for a callback to indicate lock release, we can't |
251 | * back by the server, and so if might be possible to get a | 362 | * actually rely on this, so need to recheck at regular intervals. The |
252 | * lock we're currently waiting for. | 363 | * problem is that the server might not notify us if the lock just |
253 | */ | 364 | * expires (say because a client died) rather than being explicitly |
365 | * released. | ||
366 | */ | ||
254 | case AFS_VNODE_LOCK_WAITING_FOR_CB: | 367 | case AFS_VNODE_LOCK_WAITING_FOR_CB: |
255 | _debug("get"); | 368 | _debug("retry"); |
256 | 369 | afs_next_locker(vnode, 0); | |
257 | key = key_get(vnode->lock_key); | ||
258 | type = vnode->lock_type; | ||
259 | vnode->lock_state = AFS_VNODE_LOCK_SETTING; | ||
260 | spin_unlock(&vnode->lock); | 370 | spin_unlock(&vnode->lock); |
371 | return; | ||
261 | 372 | ||
262 | ret = afs_set_lock(vnode, key, type); /* RPC */ | 373 | case AFS_VNODE_LOCK_DELETED: |
263 | key_put(key); | 374 | afs_kill_lockers_enoent(vnode); |
264 | 375 | spin_unlock(&vnode->lock); | |
265 | spin_lock(&vnode->lock); | 376 | return; |
266 | switch (ret) { | ||
267 | case -EWOULDBLOCK: | ||
268 | _debug("blocked"); | ||
269 | break; | ||
270 | case 0: | ||
271 | _debug("acquired"); | ||
272 | vnode->lock_state = AFS_VNODE_LOCK_GRANTED; | ||
273 | /* Fall through */ | ||
274 | default: | ||
275 | /* Pass the lock or the error onto the first locker in | ||
276 | * the list - if they're looking for this type of lock. | ||
277 | * If they're not, we assume that whoever asked for it | ||
278 | * took a signal. | ||
279 | */ | ||
280 | if (list_empty(&vnode->pending_locks)) { | ||
281 | _debug("withdrawn"); | ||
282 | vnode->lock_state = AFS_VNODE_LOCK_NEED_UNLOCK; | ||
283 | goto again; | ||
284 | } | ||
285 | |||
286 | fl = list_entry(vnode->pending_locks.next, | ||
287 | struct file_lock, fl_u.afs.link); | ||
288 | type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; | ||
289 | if (vnode->lock_type != type) { | ||
290 | _debug("changed"); | ||
291 | vnode->lock_state = AFS_VNODE_LOCK_NEED_UNLOCK; | ||
292 | goto again; | ||
293 | } | ||
294 | |||
295 | fl->fl_u.afs.state = ret; | ||
296 | if (ret == 0) | ||
297 | afs_grant_locks(vnode, fl); | ||
298 | else | ||
299 | list_del_init(&fl->fl_u.afs.link); | ||
300 | wake_up(&fl->fl_wait); | ||
301 | spin_unlock(&vnode->lock); | ||
302 | _leave(" [granted]"); | ||
303 | return; | ||
304 | } | ||
305 | 377 | ||
306 | /* Fall through */ | 378 | /* Fall through */ |
307 | default: | 379 | default: |
@@ -320,14 +392,16 @@ again: | |||
320 | */ | 392 | */ |
321 | static void afs_defer_unlock(struct afs_vnode *vnode) | 393 | static void afs_defer_unlock(struct afs_vnode *vnode) |
322 | { | 394 | { |
323 | _enter(""); | 395 | _enter("%u", vnode->lock_state); |
324 | 396 | ||
325 | if (vnode->lock_state == AFS_VNODE_LOCK_GRANTED || | 397 | if (list_empty(&vnode->granted_locks) && |
326 | vnode->lock_state == AFS_VNODE_LOCK_EXTENDING) { | 398 | (vnode->lock_state == AFS_VNODE_LOCK_GRANTED || |
399 | vnode->lock_state == AFS_VNODE_LOCK_EXTENDING)) { | ||
327 | cancel_delayed_work(&vnode->lock_work); | 400 | cancel_delayed_work(&vnode->lock_work); |
328 | 401 | ||
329 | vnode->lock_state = AFS_VNODE_LOCK_NEED_UNLOCK; | 402 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_NEED_UNLOCK); |
330 | afs_lock_may_be_available(vnode); | 403 | trace_afs_flock_ev(vnode, NULL, afs_flock_defer_unlock, 0); |
404 | queue_delayed_work(afs_lock_manager, &vnode->lock_work, 0); | ||
331 | } | 405 | } |
332 | } | 406 | } |
333 | 407 | ||
@@ -336,7 +410,7 @@ static void afs_defer_unlock(struct afs_vnode *vnode) | |||
336 | * whether we think that we have a locking permit. | 410 | * whether we think that we have a locking permit. |
337 | */ | 411 | */ |
338 | static int afs_do_setlk_check(struct afs_vnode *vnode, struct key *key, | 412 | static int afs_do_setlk_check(struct afs_vnode *vnode, struct key *key, |
339 | afs_lock_type_t type, bool can_sleep) | 413 | enum afs_flock_mode mode, afs_lock_type_t type) |
340 | { | 414 | { |
341 | afs_access_t access; | 415 | afs_access_t access; |
342 | int ret; | 416 | int ret; |
@@ -364,160 +438,177 @@ static int afs_do_setlk_check(struct afs_vnode *vnode, struct key *key, | |||
364 | if (type == AFS_LOCK_READ) { | 438 | if (type == AFS_LOCK_READ) { |
365 | if (!(access & (AFS_ACE_INSERT | AFS_ACE_WRITE | AFS_ACE_LOCK))) | 439 | if (!(access & (AFS_ACE_INSERT | AFS_ACE_WRITE | AFS_ACE_LOCK))) |
366 | return -EACCES; | 440 | return -EACCES; |
367 | if (vnode->status.lock_count == -1 && !can_sleep) | ||
368 | return -EAGAIN; /* Write locked */ | ||
369 | } else { | 441 | } else { |
370 | if (!(access & (AFS_ACE_INSERT | AFS_ACE_WRITE))) | 442 | if (!(access & (AFS_ACE_INSERT | AFS_ACE_WRITE))) |
371 | return -EACCES; | 443 | return -EACCES; |
372 | if (vnode->status.lock_count != 0 && !can_sleep) | ||
373 | return -EAGAIN; /* Locked */ | ||
374 | } | 444 | } |
375 | 445 | ||
376 | return 0; | 446 | return 0; |
377 | } | 447 | } |
378 | 448 | ||
379 | /* | 449 | /* |
380 | * Remove the front runner from the pending queue. | ||
381 | * - The caller must hold vnode->lock. | ||
382 | */ | ||
383 | static void afs_dequeue_lock(struct afs_vnode *vnode, struct file_lock *fl) | ||
384 | { | ||
385 | struct file_lock *next; | ||
386 | |||
387 | _enter(""); | ||
388 | |||
389 | /* ->lock_type, ->lock_key and ->lock_state only belong to this | ||
390 | * file_lock if we're at the front of the pending queue or if we have | ||
391 | * the lock granted or if the lock_state is NEED_UNLOCK or UNLOCKING. | ||
392 | */ | ||
393 | if (vnode->granted_locks.next == &fl->fl_u.afs.link && | ||
394 | vnode->granted_locks.prev == &fl->fl_u.afs.link) { | ||
395 | list_del_init(&fl->fl_u.afs.link); | ||
396 | afs_defer_unlock(vnode); | ||
397 | return; | ||
398 | } | ||
399 | |||
400 | if (!list_empty(&vnode->granted_locks) || | ||
401 | vnode->pending_locks.next != &fl->fl_u.afs.link) { | ||
402 | list_del_init(&fl->fl_u.afs.link); | ||
403 | return; | ||
404 | } | ||
405 | |||
406 | list_del_init(&fl->fl_u.afs.link); | ||
407 | key_put(vnode->lock_key); | ||
408 | vnode->lock_key = NULL; | ||
409 | vnode->lock_state = AFS_VNODE_LOCK_NONE; | ||
410 | |||
411 | if (list_empty(&vnode->pending_locks)) | ||
412 | return; | ||
413 | |||
414 | /* The new front of the queue now owns the state variables. */ | ||
415 | next = list_entry(vnode->pending_locks.next, | ||
416 | struct file_lock, fl_u.afs.link); | ||
417 | vnode->lock_key = key_get(afs_file_key(next->fl_file)); | ||
418 | vnode->lock_type = (next->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; | ||
419 | vnode->lock_state = AFS_VNODE_LOCK_WAITING_FOR_CB; | ||
420 | afs_lock_may_be_available(vnode); | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * request a lock on a file on the server | 450 | * request a lock on a file on the server |
425 | */ | 451 | */ |
426 | static int afs_do_setlk(struct file *file, struct file_lock *fl) | 452 | static int afs_do_setlk(struct file *file, struct file_lock *fl) |
427 | { | 453 | { |
428 | struct inode *inode = locks_inode(file); | 454 | struct inode *inode = locks_inode(file); |
429 | struct afs_vnode *vnode = AFS_FS_I(inode); | 455 | struct afs_vnode *vnode = AFS_FS_I(inode); |
456 | enum afs_flock_mode mode = AFS_FS_S(inode->i_sb)->flock_mode; | ||
430 | afs_lock_type_t type; | 457 | afs_lock_type_t type; |
431 | struct key *key = afs_file_key(file); | 458 | struct key *key = afs_file_key(file); |
459 | bool partial, no_server_lock = false; | ||
432 | int ret; | 460 | int ret; |
433 | 461 | ||
434 | _enter("{%llx:%llu},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type); | 462 | if (mode == afs_flock_mode_unset) |
463 | mode = afs_flock_mode_openafs; | ||
435 | 464 | ||
436 | /* only whole-file locks are supported */ | 465 | _enter("{%llx:%llu},%llu-%llu,%u,%u", |
437 | if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX) | 466 | vnode->fid.vid, vnode->fid.vnode, |
438 | return -EINVAL; | 467 | fl->fl_start, fl->fl_end, fl->fl_type, mode); |
439 | 468 | ||
440 | fl->fl_ops = &afs_lock_ops; | 469 | fl->fl_ops = &afs_lock_ops; |
441 | INIT_LIST_HEAD(&fl->fl_u.afs.link); | 470 | INIT_LIST_HEAD(&fl->fl_u.afs.link); |
442 | fl->fl_u.afs.state = AFS_LOCK_PENDING; | 471 | fl->fl_u.afs.state = AFS_LOCK_PENDING; |
443 | 472 | ||
473 | partial = (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX); | ||
444 | type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; | 474 | type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; |
475 | if (mode == afs_flock_mode_write && partial) | ||
476 | type = AFS_LOCK_WRITE; | ||
445 | 477 | ||
446 | ret = afs_do_setlk_check(vnode, key, type, fl->fl_flags & FL_SLEEP); | 478 | ret = afs_do_setlk_check(vnode, key, mode, type); |
447 | if (ret < 0) | 479 | if (ret < 0) |
448 | return ret; | 480 | return ret; |
449 | 481 | ||
450 | spin_lock(&vnode->lock); | 482 | trace_afs_flock_op(vnode, fl, afs_flock_op_set_lock); |
451 | 483 | ||
452 | /* If we've already got a readlock on the server then we instantly | 484 | /* AFS3 protocol only supports full-file locks and doesn't provide any |
453 | * grant another readlock, irrespective of whether there are any | 485 | * method of upgrade/downgrade, so we need to emulate for partial-file |
454 | * pending writelocks. | 486 | * locks. |
487 | * | ||
488 | * The OpenAFS client only gets a server lock for a full-file lock and | ||
489 | * keeps partial-file locks local. Allow this behaviour to be emulated | ||
490 | * (as the default). | ||
455 | */ | 491 | */ |
456 | if (type == AFS_LOCK_READ && | 492 | if (mode == afs_flock_mode_local || |
457 | vnode->lock_state == AFS_VNODE_LOCK_GRANTED && | 493 | (partial && mode == afs_flock_mode_openafs)) { |
458 | vnode->lock_type == AFS_LOCK_READ) { | 494 | no_server_lock = true; |
459 | _debug("instant readlock"); | 495 | goto skip_server_lock; |
460 | ASSERT(!list_empty(&vnode->granted_locks)); | ||
461 | goto share_existing_lock; | ||
462 | } | 496 | } |
463 | 497 | ||
498 | spin_lock(&vnode->lock); | ||
464 | list_add_tail(&fl->fl_u.afs.link, &vnode->pending_locks); | 499 | list_add_tail(&fl->fl_u.afs.link, &vnode->pending_locks); |
465 | 500 | ||
501 | ret = -ENOENT; | ||
502 | if (vnode->lock_state == AFS_VNODE_LOCK_DELETED) | ||
503 | goto error_unlock; | ||
504 | |||
505 | /* If we've already got a lock on the server then try to move to having | ||
506 | * the VFS grant the requested lock. Note that this means that other | ||
507 | * clients may get starved out. | ||
508 | */ | ||
509 | _debug("try %u", vnode->lock_state); | ||
510 | if (vnode->lock_state == AFS_VNODE_LOCK_GRANTED) { | ||
511 | if (type == AFS_LOCK_READ) { | ||
512 | _debug("instant readlock"); | ||
513 | list_move_tail(&fl->fl_u.afs.link, &vnode->granted_locks); | ||
514 | fl->fl_u.afs.state = AFS_LOCK_GRANTED; | ||
515 | goto vnode_is_locked_u; | ||
516 | } | ||
517 | |||
518 | if (vnode->lock_type == AFS_LOCK_WRITE) { | ||
519 | _debug("instant writelock"); | ||
520 | list_move_tail(&fl->fl_u.afs.link, &vnode->granted_locks); | ||
521 | fl->fl_u.afs.state = AFS_LOCK_GRANTED; | ||
522 | goto vnode_is_locked_u; | ||
523 | } | ||
524 | } | ||
525 | |||
526 | if (vnode->lock_state == AFS_VNODE_LOCK_NONE && | ||
527 | !(fl->fl_flags & FL_SLEEP)) { | ||
528 | ret = -EAGAIN; | ||
529 | if (type == AFS_LOCK_READ) { | ||
530 | if (vnode->status.lock_count == -1) | ||
531 | goto lock_is_contended; /* Write locked */ | ||
532 | } else { | ||
533 | if (vnode->status.lock_count != 0) | ||
534 | goto lock_is_contended; /* Locked */ | ||
535 | } | ||
536 | } | ||
537 | |||
466 | if (vnode->lock_state != AFS_VNODE_LOCK_NONE) | 538 | if (vnode->lock_state != AFS_VNODE_LOCK_NONE) |
467 | goto need_to_wait; | 539 | goto need_to_wait; |
468 | 540 | ||
541 | try_to_lock: | ||
469 | /* We don't have a lock on this vnode and we aren't currently waiting | 542 | /* We don't have a lock on this vnode and we aren't currently waiting |
470 | * for one either, so ask the server for a lock. | 543 | * for one either, so ask the server for a lock. |
471 | * | 544 | * |
472 | * Note that we need to be careful if we get interrupted by a signal | 545 | * Note that we need to be careful if we get interrupted by a signal |
473 | * after dispatching the request as we may still get the lock, even | 546 | * after dispatching the request as we may still get the lock, even |
474 | * though we don't wait for the reply (it's not too bad a problem - the | 547 | * though we don't wait for the reply (it's not too bad a problem - the |
475 | * lock will expire in 10 mins anyway). | 548 | * lock will expire in 5 mins anyway). |
476 | */ | 549 | */ |
477 | _debug("not locked"); | 550 | trace_afs_flock_ev(vnode, fl, afs_flock_try_to_lock, 0); |
478 | vnode->lock_key = key_get(key); | 551 | vnode->lock_key = key_get(key); |
479 | vnode->lock_type = type; | 552 | vnode->lock_type = type; |
480 | vnode->lock_state = AFS_VNODE_LOCK_SETTING; | 553 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_SETTING); |
481 | spin_unlock(&vnode->lock); | 554 | spin_unlock(&vnode->lock); |
482 | 555 | ||
483 | ret = afs_set_lock(vnode, key, type); /* RPC */ | 556 | ret = afs_set_lock(vnode, key, type); /* RPC */ |
484 | 557 | ||
485 | spin_lock(&vnode->lock); | 558 | spin_lock(&vnode->lock); |
486 | switch (ret) { | 559 | switch (ret) { |
560 | case -EKEYREJECTED: | ||
561 | case -EKEYEXPIRED: | ||
562 | case -EKEYREVOKED: | ||
563 | case -EPERM: | ||
564 | case -EACCES: | ||
565 | fl->fl_u.afs.state = ret; | ||
566 | trace_afs_flock_ev(vnode, fl, afs_flock_fail_perm, ret); | ||
567 | list_del_init(&fl->fl_u.afs.link); | ||
568 | afs_next_locker(vnode, ret); | ||
569 | goto error_unlock; | ||
570 | |||
571 | case -ENOENT: | ||
572 | fl->fl_u.afs.state = ret; | ||
573 | trace_afs_flock_ev(vnode, fl, afs_flock_fail_other, ret); | ||
574 | list_del_init(&fl->fl_u.afs.link); | ||
575 | afs_kill_lockers_enoent(vnode); | ||
576 | goto error_unlock; | ||
577 | |||
487 | default: | 578 | default: |
488 | goto abort_attempt; | 579 | fl->fl_u.afs.state = ret; |
580 | trace_afs_flock_ev(vnode, fl, afs_flock_fail_other, ret); | ||
581 | list_del_init(&fl->fl_u.afs.link); | ||
582 | afs_next_locker(vnode, 0); | ||
583 | goto error_unlock; | ||
489 | 584 | ||
490 | case -EWOULDBLOCK: | 585 | case -EWOULDBLOCK: |
491 | /* The server doesn't have a lock-waiting queue, so the client | 586 | /* The server doesn't have a lock-waiting queue, so the client |
492 | * will have to retry. The server will break the outstanding | 587 | * will have to retry. The server will break the outstanding |
493 | * callbacks on a file when a lock is released. | 588 | * callbacks on a file when a lock is released. |
494 | */ | 589 | */ |
495 | _debug("would block"); | ||
496 | ASSERT(list_empty(&vnode->granted_locks)); | 590 | ASSERT(list_empty(&vnode->granted_locks)); |
497 | ASSERTCMP(vnode->pending_locks.next, ==, &fl->fl_u.afs.link); | 591 | ASSERTCMP(vnode->pending_locks.next, ==, &fl->fl_u.afs.link); |
498 | vnode->lock_state = AFS_VNODE_LOCK_WAITING_FOR_CB; | 592 | goto lock_is_contended; |
499 | goto need_to_wait; | ||
500 | 593 | ||
501 | case 0: | 594 | case 0: |
502 | _debug("acquired"); | 595 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_GRANTED); |
503 | break; | 596 | trace_afs_flock_ev(vnode, fl, afs_flock_acquired, type); |
597 | afs_grant_locks(vnode); | ||
598 | goto vnode_is_locked_u; | ||
504 | } | 599 | } |
505 | 600 | ||
506 | /* we've acquired a server lock, but it needs to be renewed after 5 | 601 | vnode_is_locked_u: |
507 | * mins */ | ||
508 | vnode->lock_state = AFS_VNODE_LOCK_GRANTED; | ||
509 | afs_schedule_lock_extension(vnode); | ||
510 | |||
511 | share_existing_lock: | ||
512 | /* the lock has been granted as far as we're concerned... */ | ||
513 | fl->fl_u.afs.state = AFS_LOCK_GRANTED; | ||
514 | list_move_tail(&fl->fl_u.afs.link, &vnode->granted_locks); | ||
515 | |||
516 | given_lock: | ||
517 | /* ... but we do still need to get the VFS's blessing */ | ||
518 | spin_unlock(&vnode->lock); | 602 | spin_unlock(&vnode->lock); |
519 | 603 | vnode_is_locked: | |
520 | ret = posix_lock_file(file, fl, NULL); | 604 | /* the lock has been granted by the server... */ |
605 | ASSERTCMP(fl->fl_u.afs.state, ==, AFS_LOCK_GRANTED); | ||
606 | |||
607 | skip_server_lock: | ||
608 | /* ... but the VFS still needs to distribute access on this client. */ | ||
609 | trace_afs_flock_ev(vnode, fl, afs_flock_vfs_locking, 0); | ||
610 | ret = locks_lock_file_wait(file, fl); | ||
611 | trace_afs_flock_ev(vnode, fl, afs_flock_vfs_lock, ret); | ||
521 | if (ret < 0) | 612 | if (ret < 0) |
522 | goto vfs_rejected_lock; | 613 | goto vfs_rejected_lock; |
523 | 614 | ||
@@ -529,38 +620,62 @@ given_lock: | |||
529 | _leave(" = 0"); | 620 | _leave(" = 0"); |
530 | return 0; | 621 | return 0; |
531 | 622 | ||
623 | lock_is_contended: | ||
624 | if (!(fl->fl_flags & FL_SLEEP)) { | ||
625 | list_del_init(&fl->fl_u.afs.link); | ||
626 | afs_next_locker(vnode, 0); | ||
627 | ret = -EAGAIN; | ||
628 | goto error_unlock; | ||
629 | } | ||
630 | |||
631 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_WAITING_FOR_CB); | ||
632 | trace_afs_flock_ev(vnode, fl, afs_flock_would_block, ret); | ||
633 | queue_delayed_work(afs_lock_manager, &vnode->lock_work, HZ * 5); | ||
634 | |||
532 | need_to_wait: | 635 | need_to_wait: |
533 | /* We're going to have to wait. Either this client doesn't have a lock | 636 | /* We're going to have to wait. Either this client doesn't have a lock |
534 | * on the server yet and we need to wait for a callback to occur, or | 637 | * on the server yet and we need to wait for a callback to occur, or |
535 | * the client does have a lock on the server, but it belongs to some | 638 | * the client does have a lock on the server, but it's shared and we |
536 | * other process(es) and is incompatible with the lock we want. | 639 | * need an exclusive lock. |
537 | */ | 640 | */ |
538 | ret = -EAGAIN; | 641 | spin_unlock(&vnode->lock); |
539 | if (fl->fl_flags & FL_SLEEP) { | ||
540 | spin_unlock(&vnode->lock); | ||
541 | 642 | ||
542 | _debug("sleep"); | 643 | trace_afs_flock_ev(vnode, fl, afs_flock_waiting, 0); |
543 | ret = wait_event_interruptible(fl->fl_wait, | 644 | ret = wait_event_interruptible(fl->fl_wait, |
544 | fl->fl_u.afs.state != AFS_LOCK_PENDING); | 645 | fl->fl_u.afs.state != AFS_LOCK_PENDING); |
646 | trace_afs_flock_ev(vnode, fl, afs_flock_waited, ret); | ||
545 | 647 | ||
648 | if (fl->fl_u.afs.state >= 0 && fl->fl_u.afs.state != AFS_LOCK_GRANTED) { | ||
546 | spin_lock(&vnode->lock); | 649 | spin_lock(&vnode->lock); |
547 | } | ||
548 | 650 | ||
549 | if (fl->fl_u.afs.state == AFS_LOCK_GRANTED) | 651 | switch (fl->fl_u.afs.state) { |
550 | goto given_lock; | 652 | case AFS_LOCK_YOUR_TRY: |
551 | if (fl->fl_u.afs.state < 0) | 653 | fl->fl_u.afs.state = AFS_LOCK_PENDING; |
552 | ret = fl->fl_u.afs.state; | 654 | goto try_to_lock; |
655 | case AFS_LOCK_PENDING: | ||
656 | if (ret > 0) { | ||
657 | /* We need to retry the lock. We may not be | ||
658 | * notified by the server if it just expired | ||
659 | * rather than being released. | ||
660 | */ | ||
661 | ASSERTCMP(vnode->lock_state, ==, AFS_VNODE_LOCK_WAITING_FOR_CB); | ||
662 | afs_set_lock_state(vnode, AFS_VNODE_LOCK_SETTING); | ||
663 | fl->fl_u.afs.state = AFS_LOCK_PENDING; | ||
664 | goto try_to_lock; | ||
665 | } | ||
666 | goto error_unlock; | ||
667 | case AFS_LOCK_GRANTED: | ||
668 | default: | ||
669 | break; | ||
670 | } | ||
553 | 671 | ||
554 | abort_attempt: | 672 | spin_unlock(&vnode->lock); |
555 | /* we aren't going to get the lock, either because we're unwilling to | 673 | } |
556 | * wait, or because some signal happened */ | ||
557 | _debug("abort"); | ||
558 | afs_dequeue_lock(vnode, fl); | ||
559 | 674 | ||
560 | error_unlock: | 675 | if (fl->fl_u.afs.state == AFS_LOCK_GRANTED) |
561 | spin_unlock(&vnode->lock); | 676 | goto vnode_is_locked; |
562 | _leave(" = %d", ret); | 677 | ret = fl->fl_u.afs.state; |
563 | return ret; | 678 | goto error; |
564 | 679 | ||
565 | vfs_rejected_lock: | 680 | vfs_rejected_lock: |
566 | /* The VFS rejected the lock we just obtained, so we have to discard | 681 | /* The VFS rejected the lock we just obtained, so we have to discard |
@@ -568,11 +683,17 @@ vfs_rejected_lock: | |||
568 | * deal with. | 683 | * deal with. |
569 | */ | 684 | */ |
570 | _debug("vfs refused %d", ret); | 685 | _debug("vfs refused %d", ret); |
686 | if (no_server_lock) | ||
687 | goto error; | ||
571 | spin_lock(&vnode->lock); | 688 | spin_lock(&vnode->lock); |
572 | list_del_init(&fl->fl_u.afs.link); | 689 | list_del_init(&fl->fl_u.afs.link); |
573 | if (list_empty(&vnode->granted_locks)) | 690 | afs_defer_unlock(vnode); |
574 | afs_defer_unlock(vnode); | 691 | |
575 | goto error_unlock; | 692 | error_unlock: |
693 | spin_unlock(&vnode->lock); | ||
694 | error: | ||
695 | _leave(" = %d", ret); | ||
696 | return ret; | ||
576 | } | 697 | } |
577 | 698 | ||
578 | /* | 699 | /* |
@@ -585,14 +706,12 @@ static int afs_do_unlk(struct file *file, struct file_lock *fl) | |||
585 | 706 | ||
586 | _enter("{%llx:%llu},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type); | 707 | _enter("{%llx:%llu},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type); |
587 | 708 | ||
709 | trace_afs_flock_op(vnode, fl, afs_flock_op_unlock); | ||
710 | |||
588 | /* Flush all pending writes before doing anything with locks. */ | 711 | /* Flush all pending writes before doing anything with locks. */ |
589 | vfs_fsync(file, 0); | 712 | vfs_fsync(file, 0); |
590 | 713 | ||
591 | /* only whole-file unlocks are supported */ | 714 | ret = locks_lock_file_wait(file, fl); |
592 | if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX) | ||
593 | return -EINVAL; | ||
594 | |||
595 | ret = posix_lock_file(file, fl, NULL); | ||
596 | _leave(" = %d [%u]", ret, vnode->lock_state); | 715 | _leave(" = %d [%u]", ret, vnode->lock_state); |
597 | return ret; | 716 | return ret; |
598 | } | 717 | } |
@@ -608,6 +727,9 @@ static int afs_do_getlk(struct file *file, struct file_lock *fl) | |||
608 | 727 | ||
609 | _enter(""); | 728 | _enter(""); |
610 | 729 | ||
730 | if (vnode->lock_state == AFS_VNODE_LOCK_DELETED) | ||
731 | return -ENOENT; | ||
732 | |||
611 | fl->fl_type = F_UNLCK; | 733 | fl->fl_type = F_UNLCK; |
612 | 734 | ||
613 | /* check local lock records first */ | 735 | /* check local lock records first */ |
@@ -619,12 +741,15 @@ static int afs_do_getlk(struct file *file, struct file_lock *fl) | |||
619 | goto error; | 741 | goto error; |
620 | 742 | ||
621 | lock_count = READ_ONCE(vnode->status.lock_count); | 743 | lock_count = READ_ONCE(vnode->status.lock_count); |
622 | if (lock_count > 0) | 744 | if (lock_count != 0) { |
623 | fl->fl_type = F_RDLCK; | 745 | if (lock_count > 0) |
624 | else | 746 | fl->fl_type = F_RDLCK; |
625 | fl->fl_type = F_WRLCK; | 747 | else |
626 | fl->fl_start = 0; | 748 | fl->fl_type = F_WRLCK; |
627 | fl->fl_end = OFFSET_MAX; | 749 | fl->fl_start = 0; |
750 | fl->fl_end = OFFSET_MAX; | ||
751 | fl->fl_pid = 0; | ||
752 | } | ||
628 | } | 753 | } |
629 | 754 | ||
630 | ret = 0; | 755 | ret = 0; |
@@ -639,6 +764,8 @@ error: | |||
639 | int afs_lock(struct file *file, int cmd, struct file_lock *fl) | 764 | int afs_lock(struct file *file, int cmd, struct file_lock *fl) |
640 | { | 765 | { |
641 | struct afs_vnode *vnode = AFS_FS_I(locks_inode(file)); | 766 | struct afs_vnode *vnode = AFS_FS_I(locks_inode(file)); |
767 | enum afs_flock_operation op; | ||
768 | int ret; | ||
642 | 769 | ||
643 | _enter("{%llx:%llu},%d,{t=%x,fl=%x,r=%Ld:%Ld}", | 770 | _enter("{%llx:%llu},%d,{t=%x,fl=%x,r=%Ld:%Ld}", |
644 | vnode->fid.vid, vnode->fid.vnode, cmd, | 771 | vnode->fid.vid, vnode->fid.vnode, cmd, |
@@ -651,9 +778,23 @@ int afs_lock(struct file *file, int cmd, struct file_lock *fl) | |||
651 | 778 | ||
652 | if (IS_GETLK(cmd)) | 779 | if (IS_GETLK(cmd)) |
653 | return afs_do_getlk(file, fl); | 780 | return afs_do_getlk(file, fl); |
781 | |||
782 | fl->fl_u.afs.debug_id = atomic_inc_return(&afs_file_lock_debug_id); | ||
783 | trace_afs_flock_op(vnode, fl, afs_flock_op_lock); | ||
784 | |||
654 | if (fl->fl_type == F_UNLCK) | 785 | if (fl->fl_type == F_UNLCK) |
655 | return afs_do_unlk(file, fl); | 786 | ret = afs_do_unlk(file, fl); |
656 | return afs_do_setlk(file, fl); | 787 | else |
788 | ret = afs_do_setlk(file, fl); | ||
789 | |||
790 | switch (ret) { | ||
791 | case 0: op = afs_flock_op_return_ok; break; | ||
792 | case -EAGAIN: op = afs_flock_op_return_eagain; break; | ||
793 | case -EDEADLK: op = afs_flock_op_return_edeadlk; break; | ||
794 | default: op = afs_flock_op_return_error; break; | ||
795 | } | ||
796 | trace_afs_flock_op(vnode, fl, op); | ||
797 | return ret; | ||
657 | } | 798 | } |
658 | 799 | ||
659 | /* | 800 | /* |
@@ -662,6 +803,8 @@ int afs_lock(struct file *file, int cmd, struct file_lock *fl) | |||
662 | int afs_flock(struct file *file, int cmd, struct file_lock *fl) | 803 | int afs_flock(struct file *file, int cmd, struct file_lock *fl) |
663 | { | 804 | { |
664 | struct afs_vnode *vnode = AFS_FS_I(locks_inode(file)); | 805 | struct afs_vnode *vnode = AFS_FS_I(locks_inode(file)); |
806 | enum afs_flock_operation op; | ||
807 | int ret; | ||
665 | 808 | ||
666 | _enter("{%llx:%llu},%d,{t=%x,fl=%x}", | 809 | _enter("{%llx:%llu},%d,{t=%x,fl=%x}", |
667 | vnode->fid.vid, vnode->fid.vnode, cmd, | 810 | vnode->fid.vid, vnode->fid.vnode, cmd, |
@@ -677,10 +820,23 @@ int afs_flock(struct file *file, int cmd, struct file_lock *fl) | |||
677 | if (!(fl->fl_flags & FL_FLOCK)) | 820 | if (!(fl->fl_flags & FL_FLOCK)) |
678 | return -ENOLCK; | 821 | return -ENOLCK; |
679 | 822 | ||
823 | fl->fl_u.afs.debug_id = atomic_inc_return(&afs_file_lock_debug_id); | ||
824 | trace_afs_flock_op(vnode, fl, afs_flock_op_flock); | ||
825 | |||
680 | /* we're simulating flock() locks using posix locks on the server */ | 826 | /* we're simulating flock() locks using posix locks on the server */ |
681 | if (fl->fl_type == F_UNLCK) | 827 | if (fl->fl_type == F_UNLCK) |
682 | return afs_do_unlk(file, fl); | 828 | ret = afs_do_unlk(file, fl); |
683 | return afs_do_setlk(file, fl); | 829 | else |
830 | ret = afs_do_setlk(file, fl); | ||
831 | |||
832 | switch (ret) { | ||
833 | case 0: op = afs_flock_op_return_ok; break; | ||
834 | case -EAGAIN: op = afs_flock_op_return_eagain; break; | ||
835 | case -EDEADLK: op = afs_flock_op_return_edeadlk; break; | ||
836 | default: op = afs_flock_op_return_error; break; | ||
837 | } | ||
838 | trace_afs_flock_op(vnode, fl, op); | ||
839 | return ret; | ||
684 | } | 840 | } |
685 | 841 | ||
686 | /* | 842 | /* |
@@ -695,7 +851,10 @@ static void afs_fl_copy_lock(struct file_lock *new, struct file_lock *fl) | |||
695 | 851 | ||
696 | _enter(""); | 852 | _enter(""); |
697 | 853 | ||
854 | new->fl_u.afs.debug_id = atomic_inc_return(&afs_file_lock_debug_id); | ||
855 | |||
698 | spin_lock(&vnode->lock); | 856 | spin_lock(&vnode->lock); |
857 | trace_afs_flock_op(vnode, new, afs_flock_op_copy_lock); | ||
699 | list_add(&new->fl_u.afs.link, &fl->fl_u.afs.link); | 858 | list_add(&new->fl_u.afs.link, &fl->fl_u.afs.link); |
700 | spin_unlock(&vnode->lock); | 859 | spin_unlock(&vnode->lock); |
701 | } | 860 | } |
@@ -711,7 +870,12 @@ static void afs_fl_release_private(struct file_lock *fl) | |||
711 | _enter(""); | 870 | _enter(""); |
712 | 871 | ||
713 | spin_lock(&vnode->lock); | 872 | spin_lock(&vnode->lock); |
714 | afs_dequeue_lock(vnode, fl); | 873 | |
874 | trace_afs_flock_op(vnode, fl, afs_flock_op_release_lock); | ||
875 | list_del_init(&fl->fl_u.afs.link); | ||
876 | if (list_empty(&vnode->granted_locks)) | ||
877 | afs_defer_unlock(vnode); | ||
878 | |||
715 | _debug("state %u for %p", vnode->lock_state, vnode); | 879 | _debug("state %u for %p", vnode->lock_state, vnode); |
716 | spin_unlock(&vnode->lock); | 880 | spin_unlock(&vnode->lock); |
717 | } | 881 | } |
diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c index 3a9eaec06756..5d3abde52a0f 100644 --- a/fs/afs/fs_probe.c +++ b/fs/afs/fs_probe.c | |||
@@ -141,8 +141,8 @@ static int afs_do_probe_fileserver(struct afs_net *net, | |||
141 | struct afs_addr_cursor ac = { | 141 | struct afs_addr_cursor ac = { |
142 | .index = 0, | 142 | .index = 0, |
143 | }; | 143 | }; |
144 | struct afs_call *call; | ||
144 | bool in_progress = false; | 145 | bool in_progress = false; |
145 | int err; | ||
146 | 146 | ||
147 | _enter("%pU", &server->uuid); | 147 | _enter("%pU", &server->uuid); |
148 | 148 | ||
@@ -156,12 +156,13 @@ static int afs_do_probe_fileserver(struct afs_net *net, | |||
156 | server->probe.rtt = UINT_MAX; | 156 | server->probe.rtt = UINT_MAX; |
157 | 157 | ||
158 | for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) { | 158 | for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) { |
159 | err = afs_fs_get_capabilities(net, server, &ac, key, server_index, | 159 | call = afs_fs_get_capabilities(net, server, &ac, key, server_index); |
160 | true); | 160 | if (!IS_ERR(call)) { |
161 | if (err == -EINPROGRESS) | 161 | afs_put_call(call); |
162 | in_progress = true; | 162 | in_progress = true; |
163 | else | 163 | } else { |
164 | afs_prioritise_error(_e, err, ac.abort_code); | 164 | afs_prioritise_error(_e, PTR_ERR(call), ac.abort_code); |
165 | } | ||
165 | } | 166 | } |
166 | 167 | ||
167 | if (!in_progress) | 168 | if (!in_progress) |
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index b68471ce5c35..1296f5dc4c1e 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -468,7 +468,9 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy | |||
468 | call->cb_break = fc->cb_break; | 468 | call->cb_break = fc->cb_break; |
469 | afs_use_fs_server(call, fc->cbi); | 469 | afs_use_fs_server(call, fc->cbi); |
470 | trace_afs_make_fs_call(call, &vnode->fid); | 470 | trace_afs_make_fs_call(call, &vnode->fid); |
471 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 471 | |
472 | afs_make_call(&fc->ac, call, GFP_NOFS); | ||
473 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
472 | } | 474 | } |
473 | 475 | ||
474 | /* | 476 | /* |
@@ -662,7 +664,8 @@ static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req) | |||
662 | call->cb_break = fc->cb_break; | 664 | call->cb_break = fc->cb_break; |
663 | afs_use_fs_server(call, fc->cbi); | 665 | afs_use_fs_server(call, fc->cbi); |
664 | trace_afs_make_fs_call(call, &vnode->fid); | 666 | trace_afs_make_fs_call(call, &vnode->fid); |
665 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 667 | afs_make_call(&fc->ac, call, GFP_NOFS); |
668 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
666 | } | 669 | } |
667 | 670 | ||
668 | /* | 671 | /* |
@@ -709,7 +712,8 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req) | |||
709 | call->cb_break = fc->cb_break; | 712 | call->cb_break = fc->cb_break; |
710 | afs_use_fs_server(call, fc->cbi); | 713 | afs_use_fs_server(call, fc->cbi); |
711 | trace_afs_make_fs_call(call, &vnode->fid); | 714 | trace_afs_make_fs_call(call, &vnode->fid); |
712 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 715 | afs_make_call(&fc->ac, call, GFP_NOFS); |
716 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
713 | } | 717 | } |
714 | 718 | ||
715 | /* | 719 | /* |
@@ -828,14 +832,16 @@ int afs_fs_create(struct afs_fs_cursor *fc, | |||
828 | *bp++ = 0; /* segment size */ | 832 | *bp++ = 0; /* segment size */ |
829 | 833 | ||
830 | afs_use_fs_server(call, fc->cbi); | 834 | afs_use_fs_server(call, fc->cbi); |
831 | trace_afs_make_fs_call(call, &vnode->fid); | 835 | trace_afs_make_fs_call1(call, &vnode->fid, name); |
832 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 836 | afs_make_call(&fc->ac, call, GFP_NOFS); |
837 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
833 | } | 838 | } |
834 | 839 | ||
835 | /* | 840 | /* |
836 | * deliver reply data to an FS.RemoveFile or FS.RemoveDir | 841 | * Deliver reply data to any operation that returns file status and volume |
842 | * sync. | ||
837 | */ | 843 | */ |
838 | static int afs_deliver_fs_remove(struct afs_call *call) | 844 | static int afs_deliver_fs_status_and_vol(struct afs_call *call) |
839 | { | 845 | { |
840 | struct afs_vnode *vnode = call->reply[0]; | 846 | struct afs_vnode *vnode = call->reply[0]; |
841 | const __be32 *bp; | 847 | const __be32 *bp; |
@@ -865,14 +871,14 @@ static int afs_deliver_fs_remove(struct afs_call *call) | |||
865 | static const struct afs_call_type afs_RXFSRemoveFile = { | 871 | static const struct afs_call_type afs_RXFSRemoveFile = { |
866 | .name = "FS.RemoveFile", | 872 | .name = "FS.RemoveFile", |
867 | .op = afs_FS_RemoveFile, | 873 | .op = afs_FS_RemoveFile, |
868 | .deliver = afs_deliver_fs_remove, | 874 | .deliver = afs_deliver_fs_status_and_vol, |
869 | .destructor = afs_flat_call_destructor, | 875 | .destructor = afs_flat_call_destructor, |
870 | }; | 876 | }; |
871 | 877 | ||
872 | static const struct afs_call_type afs_RXFSRemoveDir = { | 878 | static const struct afs_call_type afs_RXFSRemoveDir = { |
873 | .name = "FS.RemoveDir", | 879 | .name = "FS.RemoveDir", |
874 | .op = afs_FS_RemoveDir, | 880 | .op = afs_FS_RemoveDir, |
875 | .deliver = afs_deliver_fs_remove, | 881 | .deliver = afs_deliver_fs_status_and_vol, |
876 | .destructor = afs_flat_call_destructor, | 882 | .destructor = afs_flat_call_destructor, |
877 | }; | 883 | }; |
878 | 884 | ||
@@ -923,8 +929,9 @@ int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, | |||
923 | } | 929 | } |
924 | 930 | ||
925 | afs_use_fs_server(call, fc->cbi); | 931 | afs_use_fs_server(call, fc->cbi); |
926 | trace_afs_make_fs_call(call, &dvnode->fid); | 932 | trace_afs_make_fs_call1(call, &dvnode->fid, name); |
927 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 933 | afs_make_call(&fc->ac, call, GFP_NOFS); |
934 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
928 | } | 935 | } |
929 | 936 | ||
930 | /* | 937 | /* |
@@ -1015,8 +1022,9 @@ int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, | |||
1015 | *bp++ = htonl(vnode->fid.unique); | 1022 | *bp++ = htonl(vnode->fid.unique); |
1016 | 1023 | ||
1017 | afs_use_fs_server(call, fc->cbi); | 1024 | afs_use_fs_server(call, fc->cbi); |
1018 | trace_afs_make_fs_call(call, &vnode->fid); | 1025 | trace_afs_make_fs_call1(call, &vnode->fid, name); |
1019 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1026 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1027 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1020 | } | 1028 | } |
1021 | 1029 | ||
1022 | /* | 1030 | /* |
@@ -1129,8 +1137,9 @@ int afs_fs_symlink(struct afs_fs_cursor *fc, | |||
1129 | *bp++ = 0; /* segment size */ | 1137 | *bp++ = 0; /* segment size */ |
1130 | 1138 | ||
1131 | afs_use_fs_server(call, fc->cbi); | 1139 | afs_use_fs_server(call, fc->cbi); |
1132 | trace_afs_make_fs_call(call, &vnode->fid); | 1140 | trace_afs_make_fs_call1(call, &vnode->fid, name); |
1133 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1141 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1142 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1134 | } | 1143 | } |
1135 | 1144 | ||
1136 | /* | 1145 | /* |
@@ -1247,8 +1256,9 @@ int afs_fs_rename(struct afs_fs_cursor *fc, | |||
1247 | } | 1256 | } |
1248 | 1257 | ||
1249 | afs_use_fs_server(call, fc->cbi); | 1258 | afs_use_fs_server(call, fc->cbi); |
1250 | trace_afs_make_fs_call(call, &orig_dvnode->fid); | 1259 | trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name); |
1251 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1260 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1261 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1252 | } | 1262 | } |
1253 | 1263 | ||
1254 | /* | 1264 | /* |
@@ -1352,7 +1362,8 @@ static int afs_fs_store_data64(struct afs_fs_cursor *fc, | |||
1352 | *bp++ = htonl((u32) i_size); | 1362 | *bp++ = htonl((u32) i_size); |
1353 | 1363 | ||
1354 | trace_afs_make_fs_call(call, &vnode->fid); | 1364 | trace_afs_make_fs_call(call, &vnode->fid); |
1355 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1365 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1366 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1356 | } | 1367 | } |
1357 | 1368 | ||
1358 | /* | 1369 | /* |
@@ -1428,7 +1439,8 @@ int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, | |||
1428 | 1439 | ||
1429 | afs_use_fs_server(call, fc->cbi); | 1440 | afs_use_fs_server(call, fc->cbi); |
1430 | trace_afs_make_fs_call(call, &vnode->fid); | 1441 | trace_afs_make_fs_call(call, &vnode->fid); |
1431 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1442 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1443 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1432 | } | 1444 | } |
1433 | 1445 | ||
1434 | /* | 1446 | /* |
@@ -1526,7 +1538,8 @@ static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr) | |||
1526 | 1538 | ||
1527 | afs_use_fs_server(call, fc->cbi); | 1539 | afs_use_fs_server(call, fc->cbi); |
1528 | trace_afs_make_fs_call(call, &vnode->fid); | 1540 | trace_afs_make_fs_call(call, &vnode->fid); |
1529 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1541 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1542 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1530 | } | 1543 | } |
1531 | 1544 | ||
1532 | /* | 1545 | /* |
@@ -1572,7 +1585,8 @@ static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr) | |||
1572 | 1585 | ||
1573 | afs_use_fs_server(call, fc->cbi); | 1586 | afs_use_fs_server(call, fc->cbi); |
1574 | trace_afs_make_fs_call(call, &vnode->fid); | 1587 | trace_afs_make_fs_call(call, &vnode->fid); |
1575 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1588 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1589 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1576 | } | 1590 | } |
1577 | 1591 | ||
1578 | /* | 1592 | /* |
@@ -1616,7 +1630,8 @@ int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr) | |||
1616 | 1630 | ||
1617 | afs_use_fs_server(call, fc->cbi); | 1631 | afs_use_fs_server(call, fc->cbi); |
1618 | trace_afs_make_fs_call(call, &vnode->fid); | 1632 | trace_afs_make_fs_call(call, &vnode->fid); |
1619 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1633 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1634 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1620 | } | 1635 | } |
1621 | 1636 | ||
1622 | /* | 1637 | /* |
@@ -1800,7 +1815,8 @@ int afs_fs_get_volume_status(struct afs_fs_cursor *fc, | |||
1800 | 1815 | ||
1801 | afs_use_fs_server(call, fc->cbi); | 1816 | afs_use_fs_server(call, fc->cbi); |
1802 | trace_afs_make_fs_call(call, &vnode->fid); | 1817 | trace_afs_make_fs_call(call, &vnode->fid); |
1803 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1818 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1819 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1804 | } | 1820 | } |
1805 | 1821 | ||
1806 | /* | 1822 | /* |
@@ -1832,6 +1848,7 @@ static const struct afs_call_type afs_RXFSSetLock = { | |||
1832 | .name = "FS.SetLock", | 1848 | .name = "FS.SetLock", |
1833 | .op = afs_FS_SetLock, | 1849 | .op = afs_FS_SetLock, |
1834 | .deliver = afs_deliver_fs_xxxx_lock, | 1850 | .deliver = afs_deliver_fs_xxxx_lock, |
1851 | .done = afs_lock_op_done, | ||
1835 | .destructor = afs_flat_call_destructor, | 1852 | .destructor = afs_flat_call_destructor, |
1836 | }; | 1853 | }; |
1837 | 1854 | ||
@@ -1842,6 +1859,7 @@ static const struct afs_call_type afs_RXFSExtendLock = { | |||
1842 | .name = "FS.ExtendLock", | 1859 | .name = "FS.ExtendLock", |
1843 | .op = afs_FS_ExtendLock, | 1860 | .op = afs_FS_ExtendLock, |
1844 | .deliver = afs_deliver_fs_xxxx_lock, | 1861 | .deliver = afs_deliver_fs_xxxx_lock, |
1862 | .done = afs_lock_op_done, | ||
1845 | .destructor = afs_flat_call_destructor, | 1863 | .destructor = afs_flat_call_destructor, |
1846 | }; | 1864 | }; |
1847 | 1865 | ||
@@ -1876,6 +1894,7 @@ int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) | |||
1876 | 1894 | ||
1877 | call->key = fc->key; | 1895 | call->key = fc->key; |
1878 | call->reply[0] = vnode; | 1896 | call->reply[0] = vnode; |
1897 | call->want_reply_time = true; | ||
1879 | 1898 | ||
1880 | /* marshall the parameters */ | 1899 | /* marshall the parameters */ |
1881 | bp = call->request; | 1900 | bp = call->request; |
@@ -1886,8 +1905,9 @@ int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) | |||
1886 | *bp++ = htonl(type); | 1905 | *bp++ = htonl(type); |
1887 | 1906 | ||
1888 | afs_use_fs_server(call, fc->cbi); | 1907 | afs_use_fs_server(call, fc->cbi); |
1889 | trace_afs_make_fs_call(call, &vnode->fid); | 1908 | trace_afs_make_fs_calli(call, &vnode->fid, type); |
1890 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1909 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1910 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1891 | } | 1911 | } |
1892 | 1912 | ||
1893 | /* | 1913 | /* |
@@ -1911,6 +1931,7 @@ int afs_fs_extend_lock(struct afs_fs_cursor *fc) | |||
1911 | 1931 | ||
1912 | call->key = fc->key; | 1932 | call->key = fc->key; |
1913 | call->reply[0] = vnode; | 1933 | call->reply[0] = vnode; |
1934 | call->want_reply_time = true; | ||
1914 | 1935 | ||
1915 | /* marshall the parameters */ | 1936 | /* marshall the parameters */ |
1916 | bp = call->request; | 1937 | bp = call->request; |
@@ -1921,7 +1942,8 @@ int afs_fs_extend_lock(struct afs_fs_cursor *fc) | |||
1921 | 1942 | ||
1922 | afs_use_fs_server(call, fc->cbi); | 1943 | afs_use_fs_server(call, fc->cbi); |
1923 | trace_afs_make_fs_call(call, &vnode->fid); | 1944 | trace_afs_make_fs_call(call, &vnode->fid); |
1924 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1945 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1946 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1925 | } | 1947 | } |
1926 | 1948 | ||
1927 | /* | 1949 | /* |
@@ -1955,7 +1977,8 @@ int afs_fs_release_lock(struct afs_fs_cursor *fc) | |||
1955 | 1977 | ||
1956 | afs_use_fs_server(call, fc->cbi); | 1978 | afs_use_fs_server(call, fc->cbi); |
1957 | trace_afs_make_fs_call(call, &vnode->fid); | 1979 | trace_afs_make_fs_call(call, &vnode->fid); |
1958 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1980 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1981 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1959 | } | 1982 | } |
1960 | 1983 | ||
1961 | /* | 1984 | /* |
@@ -2000,7 +2023,8 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net, | |||
2000 | *bp++ = htonl(FSGIVEUPALLCALLBACKS); | 2023 | *bp++ = htonl(FSGIVEUPALLCALLBACKS); |
2001 | 2024 | ||
2002 | /* Can't take a ref on server */ | 2025 | /* Can't take a ref on server */ |
2003 | return afs_make_call(ac, call, GFP_NOFS, false); | 2026 | afs_make_call(ac, call, GFP_NOFS); |
2027 | return afs_wait_for_call_to_complete(call, ac); | ||
2004 | } | 2028 | } |
2005 | 2029 | ||
2006 | /* | 2030 | /* |
@@ -2070,12 +2094,11 @@ static const struct afs_call_type afs_RXFSGetCapabilities = { | |||
2070 | * Probe a fileserver for the capabilities that it supports. This can | 2094 | * Probe a fileserver for the capabilities that it supports. This can |
2071 | * return up to 196 words. | 2095 | * return up to 196 words. |
2072 | */ | 2096 | */ |
2073 | int afs_fs_get_capabilities(struct afs_net *net, | 2097 | struct afs_call *afs_fs_get_capabilities(struct afs_net *net, |
2074 | struct afs_server *server, | 2098 | struct afs_server *server, |
2075 | struct afs_addr_cursor *ac, | 2099 | struct afs_addr_cursor *ac, |
2076 | struct key *key, | 2100 | struct key *key, |
2077 | unsigned int server_index, | 2101 | unsigned int server_index) |
2078 | bool async) | ||
2079 | { | 2102 | { |
2080 | struct afs_call *call; | 2103 | struct afs_call *call; |
2081 | __be32 *bp; | 2104 | __be32 *bp; |
@@ -2084,13 +2107,14 @@ int afs_fs_get_capabilities(struct afs_net *net, | |||
2084 | 2107 | ||
2085 | call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4); | 2108 | call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4); |
2086 | if (!call) | 2109 | if (!call) |
2087 | return -ENOMEM; | 2110 | return ERR_PTR(-ENOMEM); |
2088 | 2111 | ||
2089 | call->key = key; | 2112 | call->key = key; |
2090 | call->reply[0] = afs_get_server(server); | 2113 | call->reply[0] = afs_get_server(server); |
2091 | call->reply[1] = (void *)(long)server_index; | 2114 | call->reply[1] = (void *)(long)server_index; |
2092 | call->upgrade = true; | 2115 | call->upgrade = true; |
2093 | call->want_reply_time = true; | 2116 | call->want_reply_time = true; |
2117 | call->async = true; | ||
2094 | 2118 | ||
2095 | /* marshall the parameters */ | 2119 | /* marshall the parameters */ |
2096 | bp = call->request; | 2120 | bp = call->request; |
@@ -2098,7 +2122,8 @@ int afs_fs_get_capabilities(struct afs_net *net, | |||
2098 | 2122 | ||
2099 | /* Can't take a ref on server */ | 2123 | /* Can't take a ref on server */ |
2100 | trace_afs_make_fs_call(call, NULL); | 2124 | trace_afs_make_fs_call(call, NULL); |
2101 | return afs_make_call(ac, call, GFP_NOFS, async); | 2125 | afs_make_call(ac, call, GFP_NOFS); |
2126 | return call; | ||
2102 | } | 2127 | } |
2103 | 2128 | ||
2104 | /* | 2129 | /* |
@@ -2185,7 +2210,8 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc, | |||
2185 | call->cb_break = fc->cb_break; | 2210 | call->cb_break = fc->cb_break; |
2186 | afs_use_fs_server(call, fc->cbi); | 2211 | afs_use_fs_server(call, fc->cbi); |
2187 | trace_afs_make_fs_call(call, fid); | 2212 | trace_afs_make_fs_call(call, fid); |
2188 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 2213 | afs_make_call(&fc->ac, call, GFP_NOFS); |
2214 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
2189 | } | 2215 | } |
2190 | 2216 | ||
2191 | /* | 2217 | /* |
@@ -2370,5 +2396,180 @@ int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc, | |||
2370 | call->cb_break = fc->cb_break; | 2396 | call->cb_break = fc->cb_break; |
2371 | afs_use_fs_server(call, fc->cbi); | 2397 | afs_use_fs_server(call, fc->cbi); |
2372 | trace_afs_make_fs_call(call, &fids[0]); | 2398 | trace_afs_make_fs_call(call, &fids[0]); |
2373 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 2399 | afs_make_call(&fc->ac, call, GFP_NOFS); |
2400 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
2401 | } | ||
2402 | |||
2403 | /* | ||
2404 | * deliver reply data to an FS.FetchACL | ||
2405 | */ | ||
2406 | static int afs_deliver_fs_fetch_acl(struct afs_call *call) | ||
2407 | { | ||
2408 | struct afs_vnode *vnode = call->reply[1]; | ||
2409 | struct afs_acl *acl; | ||
2410 | const __be32 *bp; | ||
2411 | unsigned int size; | ||
2412 | int ret; | ||
2413 | |||
2414 | _enter("{%u}", call->unmarshall); | ||
2415 | |||
2416 | switch (call->unmarshall) { | ||
2417 | case 0: | ||
2418 | afs_extract_to_tmp(call); | ||
2419 | call->unmarshall++; | ||
2420 | |||
2421 | /* extract the returned data length */ | ||
2422 | case 1: | ||
2423 | ret = afs_extract_data(call, true); | ||
2424 | if (ret < 0) | ||
2425 | return ret; | ||
2426 | |||
2427 | size = call->count2 = ntohl(call->tmp); | ||
2428 | size = round_up(size, 4); | ||
2429 | |||
2430 | acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL); | ||
2431 | if (!acl) | ||
2432 | return -ENOMEM; | ||
2433 | call->reply[0] = acl; | ||
2434 | acl->size = call->count2; | ||
2435 | afs_extract_begin(call, acl->data, size); | ||
2436 | call->unmarshall++; | ||
2437 | |||
2438 | /* extract the returned data */ | ||
2439 | case 2: | ||
2440 | ret = afs_extract_data(call, true); | ||
2441 | if (ret < 0) | ||
2442 | return ret; | ||
2443 | |||
2444 | afs_extract_to_buf(call, (21 + 6) * 4); | ||
2445 | call->unmarshall++; | ||
2446 | |||
2447 | /* extract the metadata */ | ||
2448 | case 3: | ||
2449 | ret = afs_extract_data(call, false); | ||
2450 | if (ret < 0) | ||
2451 | return ret; | ||
2452 | |||
2453 | bp = call->buffer; | ||
2454 | ret = afs_decode_status(call, &bp, &vnode->status, vnode, | ||
2455 | &vnode->status.data_version, NULL); | ||
2456 | if (ret < 0) | ||
2457 | return ret; | ||
2458 | xdr_decode_AFSVolSync(&bp, call->reply[2]); | ||
2459 | |||
2460 | call->unmarshall++; | ||
2461 | |||
2462 | case 4: | ||
2463 | break; | ||
2464 | } | ||
2465 | |||
2466 | _leave(" = 0 [done]"); | ||
2467 | return 0; | ||
2468 | } | ||
2469 | |||
2470 | static void afs_destroy_fs_fetch_acl(struct afs_call *call) | ||
2471 | { | ||
2472 | kfree(call->reply[0]); | ||
2473 | afs_flat_call_destructor(call); | ||
2474 | } | ||
2475 | |||
2476 | /* | ||
2477 | * FS.FetchACL operation type | ||
2478 | */ | ||
2479 | static const struct afs_call_type afs_RXFSFetchACL = { | ||
2480 | .name = "FS.FetchACL", | ||
2481 | .op = afs_FS_FetchACL, | ||
2482 | .deliver = afs_deliver_fs_fetch_acl, | ||
2483 | .destructor = afs_destroy_fs_fetch_acl, | ||
2484 | }; | ||
2485 | |||
2486 | /* | ||
2487 | * Fetch the ACL for a file. | ||
2488 | */ | ||
2489 | struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *fc) | ||
2490 | { | ||
2491 | struct afs_vnode *vnode = fc->vnode; | ||
2492 | struct afs_call *call; | ||
2493 | struct afs_net *net = afs_v2net(vnode); | ||
2494 | __be32 *bp; | ||
2495 | |||
2496 | _enter(",%x,{%llx:%llu},,", | ||
2497 | key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); | ||
2498 | |||
2499 | call = afs_alloc_flat_call(net, &afs_RXFSFetchACL, 16, (21 + 6) * 4); | ||
2500 | if (!call) { | ||
2501 | fc->ac.error = -ENOMEM; | ||
2502 | return ERR_PTR(-ENOMEM); | ||
2503 | } | ||
2504 | |||
2505 | call->key = fc->key; | ||
2506 | call->reply[0] = NULL; | ||
2507 | call->reply[1] = vnode; | ||
2508 | call->reply[2] = NULL; /* volsync */ | ||
2509 | call->ret_reply0 = true; | ||
2510 | |||
2511 | /* marshall the parameters */ | ||
2512 | bp = call->request; | ||
2513 | bp[0] = htonl(FSFETCHACL); | ||
2514 | bp[1] = htonl(vnode->fid.vid); | ||
2515 | bp[2] = htonl(vnode->fid.vnode); | ||
2516 | bp[3] = htonl(vnode->fid.unique); | ||
2517 | |||
2518 | call->cb_break = fc->cb_break; | ||
2519 | afs_use_fs_server(call, fc->cbi); | ||
2520 | trace_afs_make_fs_call(call, &vnode->fid); | ||
2521 | afs_make_call(&fc->ac, call, GFP_KERNEL); | ||
2522 | return (struct afs_acl *)afs_wait_for_call_to_complete(call, &fc->ac); | ||
2523 | } | ||
2524 | |||
2525 | /* | ||
2526 | * FS.StoreACL operation type | ||
2527 | */ | ||
2528 | static const struct afs_call_type afs_RXFSStoreACL = { | ||
2529 | .name = "FS.StoreACL", | ||
2530 | .op = afs_FS_StoreACL, | ||
2531 | .deliver = afs_deliver_fs_status_and_vol, | ||
2532 | .destructor = afs_flat_call_destructor, | ||
2533 | }; | ||
2534 | |||
2535 | /* | ||
2536 | * Fetch the ACL for a file. | ||
2537 | */ | ||
2538 | int afs_fs_store_acl(struct afs_fs_cursor *fc, const struct afs_acl *acl) | ||
2539 | { | ||
2540 | struct afs_vnode *vnode = fc->vnode; | ||
2541 | struct afs_call *call; | ||
2542 | struct afs_net *net = afs_v2net(vnode); | ||
2543 | size_t size; | ||
2544 | __be32 *bp; | ||
2545 | |||
2546 | _enter(",%x,{%llx:%llu},,", | ||
2547 | key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); | ||
2548 | |||
2549 | size = round_up(acl->size, 4); | ||
2550 | call = afs_alloc_flat_call(net, &afs_RXFSStoreACL, | ||
2551 | 5 * 4 + size, (21 + 6) * 4); | ||
2552 | if (!call) { | ||
2553 | fc->ac.error = -ENOMEM; | ||
2554 | return -ENOMEM; | ||
2555 | } | ||
2556 | |||
2557 | call->key = fc->key; | ||
2558 | call->reply[0] = vnode; | ||
2559 | call->reply[2] = NULL; /* volsync */ | ||
2560 | |||
2561 | /* marshall the parameters */ | ||
2562 | bp = call->request; | ||
2563 | bp[0] = htonl(FSSTOREACL); | ||
2564 | bp[1] = htonl(vnode->fid.vid); | ||
2565 | bp[2] = htonl(vnode->fid.vnode); | ||
2566 | bp[3] = htonl(vnode->fid.unique); | ||
2567 | bp[4] = htonl(acl->size); | ||
2568 | memcpy(&bp[5], acl->data, acl->size); | ||
2569 | if (acl->size != size) | ||
2570 | memset((void *)&bp[5] + acl->size, 0, size - acl->size); | ||
2571 | |||
2572 | trace_afs_make_fs_call(call, &vnode->fid); | ||
2573 | afs_make_call(&fc->ac, call, GFP_KERNEL); | ||
2574 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
2374 | } | 2575 | } |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 9cedc3fc1b77..c4652b42d545 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -29,10 +29,36 @@ static const struct inode_operations afs_symlink_inode_operations = { | |||
29 | .listxattr = afs_listxattr, | 29 | .listxattr = afs_listxattr, |
30 | }; | 30 | }; |
31 | 31 | ||
32 | static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *parent_vnode) | ||
33 | { | ||
34 | static unsigned long once_only; | ||
35 | |||
36 | pr_warn("kAFS: AFS vnode with undefined type %u\n", | ||
37 | vnode->status.type); | ||
38 | pr_warn("kAFS: A=%d m=%o s=%llx v=%llx\n", | ||
39 | vnode->status.abort_code, | ||
40 | vnode->status.mode, | ||
41 | vnode->status.size, | ||
42 | vnode->status.data_version); | ||
43 | pr_warn("kAFS: vnode %llx:%llx:%x\n", | ||
44 | vnode->fid.vid, | ||
45 | vnode->fid.vnode, | ||
46 | vnode->fid.unique); | ||
47 | if (parent_vnode) | ||
48 | pr_warn("kAFS: dir %llx:%llx:%x\n", | ||
49 | parent_vnode->fid.vid, | ||
50 | parent_vnode->fid.vnode, | ||
51 | parent_vnode->fid.unique); | ||
52 | |||
53 | if (!test_and_set_bit(0, &once_only)) | ||
54 | dump_stack(); | ||
55 | } | ||
56 | |||
32 | /* | 57 | /* |
33 | * Initialise an inode from the vnode status. | 58 | * Initialise an inode from the vnode status. |
34 | */ | 59 | */ |
35 | static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key) | 60 | static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key, |
61 | struct afs_vnode *parent_vnode) | ||
36 | { | 62 | { |
37 | struct inode *inode = AFS_VNODE_TO_I(vnode); | 63 | struct inode *inode = AFS_VNODE_TO_I(vnode); |
38 | 64 | ||
@@ -80,12 +106,16 @@ static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key) | |||
80 | inode_nohighmem(inode); | 106 | inode_nohighmem(inode); |
81 | break; | 107 | break; |
82 | default: | 108 | default: |
83 | printk("kAFS: AFS vnode with undefined type\n"); | 109 | dump_vnode(vnode, parent_vnode); |
84 | read_sequnlock_excl(&vnode->cb_lock); | 110 | read_sequnlock_excl(&vnode->cb_lock); |
85 | return afs_protocol_error(NULL, -EBADMSG, afs_eproto_file_type); | 111 | return afs_protocol_error(NULL, -EBADMSG, afs_eproto_file_type); |
86 | } | 112 | } |
87 | 113 | ||
88 | inode->i_blocks = 0; | 114 | /* |
115 | * Estimate 512 bytes blocks used, rounded up to nearest 1K | ||
116 | * for consistency with other AFS clients. | ||
117 | */ | ||
118 | inode->i_blocks = ((i_size_read(inode) + 1023) >> 10) << 1; | ||
89 | vnode->invalid_before = vnode->status.data_version; | 119 | vnode->invalid_before = vnode->status.data_version; |
90 | 120 | ||
91 | read_sequnlock_excl(&vnode->cb_lock); | 121 | read_sequnlock_excl(&vnode->cb_lock); |
@@ -270,7 +300,8 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) | |||
270 | */ | 300 | */ |
271 | struct inode *afs_iget(struct super_block *sb, struct key *key, | 301 | struct inode *afs_iget(struct super_block *sb, struct key *key, |
272 | struct afs_fid *fid, struct afs_file_status *status, | 302 | struct afs_fid *fid, struct afs_file_status *status, |
273 | struct afs_callback *cb, struct afs_cb_interest *cbi) | 303 | struct afs_callback *cb, struct afs_cb_interest *cbi, |
304 | struct afs_vnode *parent_vnode) | ||
274 | { | 305 | { |
275 | struct afs_iget_data data = { .fid = *fid }; | 306 | struct afs_iget_data data = { .fid = *fid }; |
276 | struct afs_super_info *as; | 307 | struct afs_super_info *as; |
@@ -327,7 +358,7 @@ struct inode *afs_iget(struct super_block *sb, struct key *key, | |||
327 | vnode->cb_expires_at += ktime_get_real_seconds(); | 358 | vnode->cb_expires_at += ktime_get_real_seconds(); |
328 | } | 359 | } |
329 | 360 | ||
330 | ret = afs_inode_init_from_status(vnode, key); | 361 | ret = afs_inode_init_from_status(vnode, key, parent_vnode); |
331 | if (ret < 0) | 362 | if (ret < 0) |
332 | goto bad_inode; | 363 | goto bad_inode; |
333 | 364 | ||
@@ -543,6 +574,8 @@ void afs_evict_inode(struct inode *inode) | |||
543 | #endif | 574 | #endif |
544 | 575 | ||
545 | afs_put_permits(rcu_access_pointer(vnode->permit_cache)); | 576 | afs_put_permits(rcu_access_pointer(vnode->permit_cache)); |
577 | key_put(vnode->silly_key); | ||
578 | vnode->silly_key = NULL; | ||
546 | key_put(vnode->lock_key); | 579 | key_put(vnode->lock_key); |
547 | vnode->lock_key = NULL; | 580 | vnode->lock_key = NULL; |
548 | _leave(""); | 581 | _leave(""); |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 3904ab0b9563..b3cd6e8ad59d 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -36,11 +36,24 @@ | |||
36 | struct pagevec; | 36 | struct pagevec; |
37 | struct afs_call; | 37 | struct afs_call; |
38 | 38 | ||
39 | /* | ||
40 | * Partial file-locking emulation mode. (The problem being that AFS3 only | ||
41 | * allows whole-file locks and no upgrading/downgrading). | ||
42 | */ | ||
43 | enum afs_flock_mode { | ||
44 | afs_flock_mode_unset, | ||
45 | afs_flock_mode_local, /* Local locking only */ | ||
46 | afs_flock_mode_openafs, /* Don't get server lock for a partial lock */ | ||
47 | afs_flock_mode_strict, /* Always get a server lock for a partial lock */ | ||
48 | afs_flock_mode_write, /* Get an exclusive server lock for a partial lock */ | ||
49 | }; | ||
50 | |||
39 | struct afs_fs_context { | 51 | struct afs_fs_context { |
40 | bool force; /* T to force cell type */ | 52 | bool force; /* T to force cell type */ |
41 | bool autocell; /* T if set auto mount operation */ | 53 | bool autocell; /* T if set auto mount operation */ |
42 | bool dyn_root; /* T if dynamic root */ | 54 | bool dyn_root; /* T if dynamic root */ |
43 | bool no_cell; /* T if the source is "none" (for dynroot) */ | 55 | bool no_cell; /* T if the source is "none" (for dynroot) */ |
56 | enum afs_flock_mode flock_mode; /* Partial file-locking emulation mode */ | ||
44 | afs_voltype_t type; /* type of volume requested */ | 57 | afs_voltype_t type; /* type of volume requested */ |
45 | unsigned int volnamesz; /* size of volume name */ | 58 | unsigned int volnamesz; /* size of volume name */ |
46 | const char *volname; /* name of volume to mount */ | 59 | const char *volname; /* name of volume to mount */ |
@@ -221,6 +234,7 @@ struct afs_super_info { | |||
221 | struct net *net_ns; /* Network namespace */ | 234 | struct net *net_ns; /* Network namespace */ |
222 | struct afs_cell *cell; /* The cell in which the volume resides */ | 235 | struct afs_cell *cell; /* The cell in which the volume resides */ |
223 | struct afs_volume *volume; /* volume record */ | 236 | struct afs_volume *volume; /* volume record */ |
237 | enum afs_flock_mode flock_mode:8; /* File locking emulation mode */ | ||
224 | bool dyn_root; /* True if dynamic root */ | 238 | bool dyn_root; /* True if dynamic root */ |
225 | }; | 239 | }; |
226 | 240 | ||
@@ -599,6 +613,7 @@ enum afs_lock_state { | |||
599 | AFS_VNODE_LOCK_EXTENDING, /* We're extending a lock on the server */ | 613 | AFS_VNODE_LOCK_EXTENDING, /* We're extending a lock on the server */ |
600 | AFS_VNODE_LOCK_NEED_UNLOCK, /* We need to unlock on the server */ | 614 | AFS_VNODE_LOCK_NEED_UNLOCK, /* We need to unlock on the server */ |
601 | AFS_VNODE_LOCK_UNLOCKING, /* We're telling the server to unlock */ | 615 | AFS_VNODE_LOCK_UNLOCKING, /* We're telling the server to unlock */ |
616 | AFS_VNODE_LOCK_DELETED, /* The vnode has been deleted whilst we have a lock */ | ||
602 | }; | 617 | }; |
603 | 618 | ||
604 | /* | 619 | /* |
@@ -620,6 +635,8 @@ struct afs_vnode { | |||
620 | struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */ | 635 | struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */ |
621 | struct mutex io_lock; /* Lock for serialising I/O on this mutex */ | 636 | struct mutex io_lock; /* Lock for serialising I/O on this mutex */ |
622 | struct rw_semaphore validate_lock; /* lock for validating this vnode */ | 637 | struct rw_semaphore validate_lock; /* lock for validating this vnode */ |
638 | struct rw_semaphore rmdir_lock; /* Lock for rmdir vs sillyrename */ | ||
639 | struct key *silly_key; /* Silly rename key */ | ||
623 | spinlock_t wb_lock; /* lock for wb_keys */ | 640 | spinlock_t wb_lock; /* lock for wb_keys */ |
624 | spinlock_t lock; /* waitqueue/flags lock */ | 641 | spinlock_t lock; /* waitqueue/flags lock */ |
625 | unsigned long flags; | 642 | unsigned long flags; |
@@ -638,6 +655,7 @@ struct afs_vnode { | |||
638 | struct list_head granted_locks; /* locks granted on this file */ | 655 | struct list_head granted_locks; /* locks granted on this file */ |
639 | struct delayed_work lock_work; /* work to be done in locking */ | 656 | struct delayed_work lock_work; /* work to be done in locking */ |
640 | struct key *lock_key; /* Key to be used in lock ops */ | 657 | struct key *lock_key; /* Key to be used in lock ops */ |
658 | ktime_t locked_at; /* Time at which lock obtained */ | ||
641 | enum afs_lock_state lock_state : 8; | 659 | enum afs_lock_state lock_state : 8; |
642 | afs_lock_type_t lock_type : 8; | 660 | afs_lock_type_t lock_type : 8; |
643 | 661 | ||
@@ -864,6 +882,7 @@ extern const struct address_space_operations afs_dir_aops; | |||
864 | extern const struct dentry_operations afs_fs_dentry_operations; | 882 | extern const struct dentry_operations afs_fs_dentry_operations; |
865 | 883 | ||
866 | extern void afs_d_release(struct dentry *); | 884 | extern void afs_d_release(struct dentry *); |
885 | extern int afs_dir_remove_link(struct dentry *, struct key *, unsigned long, unsigned long); | ||
867 | 886 | ||
868 | /* | 887 | /* |
869 | * dir_edit.c | 888 | * dir_edit.c |
@@ -873,6 +892,13 @@ extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid * | |||
873 | extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason); | 892 | extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason); |
874 | 893 | ||
875 | /* | 894 | /* |
895 | * dir_silly.c | ||
896 | */ | ||
897 | extern int afs_sillyrename(struct afs_vnode *, struct afs_vnode *, | ||
898 | struct dentry *, struct key *); | ||
899 | extern int afs_silly_iput(struct dentry *, struct inode *); | ||
900 | |||
901 | /* | ||
876 | * dynroot.c | 902 | * dynroot.c |
877 | */ | 903 | */ |
878 | extern const struct file_operations afs_dynroot_file_operations; | 904 | extern const struct file_operations afs_dynroot_file_operations; |
@@ -905,6 +931,7 @@ extern void afs_put_read(struct afs_read *); | |||
905 | */ | 931 | */ |
906 | extern struct workqueue_struct *afs_lock_manager; | 932 | extern struct workqueue_struct *afs_lock_manager; |
907 | 933 | ||
934 | extern void afs_lock_op_done(struct afs_call *); | ||
908 | extern void afs_lock_work(struct work_struct *); | 935 | extern void afs_lock_work(struct work_struct *); |
909 | extern void afs_lock_may_be_available(struct afs_vnode *); | 936 | extern void afs_lock_may_be_available(struct afs_vnode *); |
910 | extern int afs_lock(struct file *, int, struct file_lock *); | 937 | extern int afs_lock(struct file *, int, struct file_lock *); |
@@ -939,8 +966,9 @@ extern int afs_fs_extend_lock(struct afs_fs_cursor *); | |||
939 | extern int afs_fs_release_lock(struct afs_fs_cursor *); | 966 | extern int afs_fs_release_lock(struct afs_fs_cursor *); |
940 | extern int afs_fs_give_up_all_callbacks(struct afs_net *, struct afs_server *, | 967 | extern int afs_fs_give_up_all_callbacks(struct afs_net *, struct afs_server *, |
941 | struct afs_addr_cursor *, struct key *); | 968 | struct afs_addr_cursor *, struct key *); |
942 | extern int afs_fs_get_capabilities(struct afs_net *, struct afs_server *, | 969 | extern struct afs_call *afs_fs_get_capabilities(struct afs_net *, struct afs_server *, |
943 | struct afs_addr_cursor *, struct key *, unsigned int, bool); | 970 | struct afs_addr_cursor *, struct key *, |
971 | unsigned int); | ||
944 | extern int afs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *, | 972 | extern int afs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *, |
945 | struct afs_fid *, struct afs_file_status *, | 973 | struct afs_fid *, struct afs_file_status *, |
946 | struct afs_callback *, unsigned int, | 974 | struct afs_callback *, unsigned int, |
@@ -949,6 +977,14 @@ extern int afs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *, | |||
949 | struct afs_fid *, struct afs_file_status *, | 977 | struct afs_fid *, struct afs_file_status *, |
950 | struct afs_callback *, struct afs_volsync *); | 978 | struct afs_callback *, struct afs_volsync *); |
951 | 979 | ||
980 | struct afs_acl { | ||
981 | u32 size; | ||
982 | u8 data[]; | ||
983 | }; | ||
984 | |||
985 | extern struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *); | ||
986 | extern int afs_fs_store_acl(struct afs_fs_cursor *, const struct afs_acl *); | ||
987 | |||
952 | /* | 988 | /* |
953 | * fs_probe.c | 989 | * fs_probe.c |
954 | */ | 990 | */ |
@@ -965,7 +1001,8 @@ extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool); | |||
965 | extern struct inode *afs_iget(struct super_block *, struct key *, | 1001 | extern struct inode *afs_iget(struct super_block *, struct key *, |
966 | struct afs_fid *, struct afs_file_status *, | 1002 | struct afs_fid *, struct afs_file_status *, |
967 | struct afs_callback *, | 1003 | struct afs_callback *, |
968 | struct afs_cb_interest *); | 1004 | struct afs_cb_interest *, |
1005 | struct afs_vnode *); | ||
969 | extern void afs_zap_data(struct afs_vnode *); | 1006 | extern void afs_zap_data(struct afs_vnode *); |
970 | extern int afs_validate(struct afs_vnode *, struct key *); | 1007 | extern int afs_validate(struct afs_vnode *, struct key *); |
971 | extern int afs_getattr(const struct path *, struct kstat *, u32, unsigned int); | 1008 | extern int afs_getattr(const struct path *, struct kstat *, u32, unsigned int); |
@@ -1073,7 +1110,8 @@ extern int __net_init afs_open_socket(struct afs_net *); | |||
1073 | extern void __net_exit afs_close_socket(struct afs_net *); | 1110 | extern void __net_exit afs_close_socket(struct afs_net *); |
1074 | extern void afs_charge_preallocation(struct work_struct *); | 1111 | extern void afs_charge_preallocation(struct work_struct *); |
1075 | extern void afs_put_call(struct afs_call *); | 1112 | extern void afs_put_call(struct afs_call *); |
1076 | extern long afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t, bool); | 1113 | extern void afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t); |
1114 | extern long afs_wait_for_call_to_complete(struct afs_call *, struct afs_addr_cursor *); | ||
1077 | extern struct afs_call *afs_alloc_flat_call(struct afs_net *, | 1115 | extern struct afs_call *afs_alloc_flat_call(struct afs_net *, |
1078 | const struct afs_call_type *, | 1116 | const struct afs_call_type *, |
1079 | size_t, size_t); | 1117 | size_t, size_t); |
@@ -1218,8 +1256,8 @@ extern void afs_fs_exit(void); | |||
1218 | extern struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *, | 1256 | extern struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *, |
1219 | const char *, int); | 1257 | const char *, int); |
1220 | extern struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *, const uuid_t *); | 1258 | extern struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *, const uuid_t *); |
1221 | extern int afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *, struct key *, | 1259 | extern struct afs_call *afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *, |
1222 | struct afs_vlserver *, unsigned int, bool); | 1260 | struct key *, struct afs_vlserver *, unsigned int); |
1223 | extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *, const uuid_t *); | 1261 | extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *, const uuid_t *); |
1224 | 1262 | ||
1225 | /* | 1263 | /* |
@@ -1333,6 +1371,20 @@ extern int yfs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *, | |||
1333 | struct afs_callback *, unsigned int, | 1371 | struct afs_callback *, unsigned int, |
1334 | struct afs_volsync *); | 1372 | struct afs_volsync *); |
1335 | 1373 | ||
1374 | struct yfs_acl { | ||
1375 | struct afs_acl *acl; /* Dir/file/symlink ACL */ | ||
1376 | struct afs_acl *vol_acl; /* Whole volume ACL */ | ||
1377 | u32 inherit_flag; /* True if ACL is inherited from parent dir */ | ||
1378 | u32 num_cleaned; /* Number of ACEs removed due to subject removal */ | ||
1379 | unsigned int flags; | ||
1380 | #define YFS_ACL_WANT_ACL 0x01 /* Set if caller wants ->acl */ | ||
1381 | #define YFS_ACL_WANT_VOL_ACL 0x02 /* Set if caller wants ->vol_acl */ | ||
1382 | }; | ||
1383 | |||
1384 | extern void yfs_free_opaque_acl(struct yfs_acl *); | ||
1385 | extern struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *, unsigned int); | ||
1386 | extern int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *, const struct afs_acl *); | ||
1387 | |||
1336 | /* | 1388 | /* |
1337 | * Miscellaneous inline functions. | 1389 | * Miscellaneous inline functions. |
1338 | */ | 1390 | */ |
diff --git a/fs/afs/protocol_yfs.h b/fs/afs/protocol_yfs.h index d443e2bfa094..915b9d10cdf3 100644 --- a/fs/afs/protocol_yfs.h +++ b/fs/afs/protocol_yfs.h | |||
@@ -31,9 +31,9 @@ enum YFS_CM_Operations { | |||
31 | }; | 31 | }; |
32 | 32 | ||
33 | enum YFS_FS_Operations { | 33 | enum YFS_FS_Operations { |
34 | YFSFETCHACL = 64131, /* YFS Fetch file ACL */ | 34 | YFSFETCHACL = 64131, /* YFS Fetch file AFS3 ACL */ |
35 | YFSFETCHSTATUS = 64132, /* YFS Fetch file status */ | 35 | YFSFETCHSTATUS = 64132, /* YFS Fetch file status */ |
36 | YFSSTOREACL = 64134, /* YFS Store file ACL */ | 36 | YFSSTOREACL = 64134, /* YFS Store file AFS3 ACL */ |
37 | YFSSTORESTATUS = 64135, /* YFS Store file status */ | 37 | YFSSTORESTATUS = 64135, /* YFS Store file status */ |
38 | YFSREMOVEFILE = 64136, /* YFS Remove a file */ | 38 | YFSREMOVEFILE = 64136, /* YFS Remove a file */ |
39 | YFSCREATEFILE = 64137, /* YFS Create a file */ | 39 | YFSCREATEFILE = 64137, /* YFS Create a file */ |
@@ -49,7 +49,7 @@ enum YFS_FS_Operations { | |||
49 | YFSRELEASELOCK = 64158, /* YFS Release a file lock */ | 49 | YFSRELEASELOCK = 64158, /* YFS Release a file lock */ |
50 | YFSLOOKUP = 64161, /* YFS lookup file in directory */ | 50 | YFSLOOKUP = 64161, /* YFS lookup file in directory */ |
51 | YFSFLUSHCPS = 64165, | 51 | YFSFLUSHCPS = 64165, |
52 | YFSFETCHOPAQUEACL = 64168, | 52 | YFSFETCHOPAQUEACL = 64168, /* YFS Fetch file YFS ACL */ |
53 | YFSWHOAMI = 64170, | 53 | YFSWHOAMI = 64170, |
54 | YFSREMOVEACL = 64171, | 54 | YFSREMOVEACL = 64171, |
55 | YFSREMOVEFILE2 = 64173, | 55 | YFSREMOVEFILE2 = 64173, |
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 3ed2c99c58ab..a34a89c75c6a 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -21,7 +21,6 @@ | |||
21 | struct workqueue_struct *afs_async_calls; | 21 | struct workqueue_struct *afs_async_calls; |
22 | 22 | ||
23 | static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); | 23 | static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); |
24 | static long afs_wait_for_call_to_complete(struct afs_call *, struct afs_addr_cursor *); | ||
25 | static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); | 24 | static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); |
26 | static void afs_delete_async_call(struct work_struct *); | 25 | static void afs_delete_async_call(struct work_struct *); |
27 | static void afs_process_async_call(struct work_struct *); | 26 | static void afs_process_async_call(struct work_struct *); |
@@ -361,10 +360,10 @@ static int afs_send_pages(struct afs_call *call, struct msghdr *msg) | |||
361 | } | 360 | } |
362 | 361 | ||
363 | /* | 362 | /* |
364 | * initiate a call | 363 | * Initiate a call and synchronously queue up the parameters for dispatch. Any |
364 | * error is stored into the call struct, which the caller must check for. | ||
365 | */ | 365 | */ |
366 | long afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, | 366 | void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp) |
367 | gfp_t gfp, bool async) | ||
368 | { | 367 | { |
369 | struct sockaddr_rxrpc *srx = &ac->alist->addrs[ac->index]; | 368 | struct sockaddr_rxrpc *srx = &ac->alist->addrs[ac->index]; |
370 | struct rxrpc_call *rxcall; | 369 | struct rxrpc_call *rxcall; |
@@ -382,7 +381,6 @@ long afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, | |||
382 | call, call->type->name, key_serial(call->key), | 381 | call, call->type->name, key_serial(call->key), |
383 | atomic_read(&call->net->nr_outstanding_calls)); | 382 | atomic_read(&call->net->nr_outstanding_calls)); |
384 | 383 | ||
385 | call->async = async; | ||
386 | call->addr_ix = ac->index; | 384 | call->addr_ix = ac->index; |
387 | call->alist = afs_get_addrlist(ac->alist); | 385 | call->alist = afs_get_addrlist(ac->alist); |
388 | 386 | ||
@@ -415,7 +413,7 @@ long afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, | |||
415 | rxcall = rxrpc_kernel_begin_call(call->net->socket, srx, call->key, | 413 | rxcall = rxrpc_kernel_begin_call(call->net->socket, srx, call->key, |
416 | (unsigned long)call, | 414 | (unsigned long)call, |
417 | tx_total_len, gfp, | 415 | tx_total_len, gfp, |
418 | (async ? | 416 | (call->async ? |
419 | afs_wake_up_async_call : | 417 | afs_wake_up_async_call : |
420 | afs_wake_up_call_waiter), | 418 | afs_wake_up_call_waiter), |
421 | call->upgrade, | 419 | call->upgrade, |
@@ -453,13 +451,11 @@ long afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, | |||
453 | 451 | ||
454 | /* Note that at this point, we may have received the reply or an abort | 452 | /* Note that at this point, we may have received the reply or an abort |
455 | * - and an asynchronous call may already have completed. | 453 | * - and an asynchronous call may already have completed. |
454 | * | ||
455 | * afs_wait_for_call_to_complete(call, ac) | ||
456 | * must be called to synchronously clean up. | ||
456 | */ | 457 | */ |
457 | if (call->async) { | 458 | return; |
458 | afs_put_call(call); | ||
459 | return -EINPROGRESS; | ||
460 | } | ||
461 | |||
462 | return afs_wait_for_call_to_complete(call, ac); | ||
463 | 459 | ||
464 | error_do_abort: | 460 | error_do_abort: |
465 | if (ret != -ECONNABORTED) { | 461 | if (ret != -ECONNABORTED) { |
@@ -495,9 +491,7 @@ error_kill_call: | |||
495 | 491 | ||
496 | ac->error = ret; | 492 | ac->error = ret; |
497 | call->state = AFS_CALL_COMPLETE; | 493 | call->state = AFS_CALL_COMPLETE; |
498 | afs_put_call(call); | ||
499 | _leave(" = %d", ret); | 494 | _leave(" = %d", ret); |
500 | return ret; | ||
501 | } | 495 | } |
502 | 496 | ||
503 | /* | 497 | /* |
@@ -604,10 +598,10 @@ call_complete: | |||
604 | } | 598 | } |
605 | 599 | ||
606 | /* | 600 | /* |
607 | * wait synchronously for a call to complete | 601 | * Wait synchronously for a call to complete and clean up the call struct. |
608 | */ | 602 | */ |
609 | static long afs_wait_for_call_to_complete(struct afs_call *call, | 603 | long afs_wait_for_call_to_complete(struct afs_call *call, |
610 | struct afs_addr_cursor *ac) | 604 | struct afs_addr_cursor *ac) |
611 | { | 605 | { |
612 | signed long rtt2, timeout; | 606 | signed long rtt2, timeout; |
613 | long ret; | 607 | long ret; |
@@ -620,6 +614,10 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, | |||
620 | 614 | ||
621 | _enter(""); | 615 | _enter(""); |
622 | 616 | ||
617 | ret = call->error; | ||
618 | if (ret < 0) | ||
619 | goto out; | ||
620 | |||
623 | rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall); | 621 | rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall); |
624 | rtt2 = nsecs_to_jiffies64(rtt) * 2; | 622 | rtt2 = nsecs_to_jiffies64(rtt) * 2; |
625 | if (rtt2 < 2) | 623 | if (rtt2 < 2) |
@@ -703,6 +701,7 @@ static long afs_wait_for_call_to_complete(struct afs_call *call, | |||
703 | break; | 701 | break; |
704 | } | 702 | } |
705 | 703 | ||
704 | out: | ||
706 | _debug("call complete"); | 705 | _debug("call complete"); |
707 | afs_put_call(call); | 706 | afs_put_call(call); |
708 | _leave(" = %p", (void *)ret); | 707 | _leave(" = %p", (void *)ret); |
diff --git a/fs/afs/super.c b/fs/afs/super.c index bab89763119b..783c68cd1a35 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -46,7 +46,7 @@ struct file_system_type afs_fs_type = { | |||
46 | .init_fs_context = afs_init_fs_context, | 46 | .init_fs_context = afs_init_fs_context, |
47 | .parameters = &afs_fs_parameters, | 47 | .parameters = &afs_fs_parameters, |
48 | .kill_sb = afs_kill_super, | 48 | .kill_sb = afs_kill_super, |
49 | .fs_flags = 0, | 49 | .fs_flags = FS_RENAME_DOES_D_MOVE, |
50 | }; | 50 | }; |
51 | MODULE_ALIAS_FS("afs"); | 51 | MODULE_ALIAS_FS("afs"); |
52 | 52 | ||
@@ -69,19 +69,30 @@ static atomic_t afs_count_active_inodes; | |||
69 | enum afs_param { | 69 | enum afs_param { |
70 | Opt_autocell, | 70 | Opt_autocell, |
71 | Opt_dyn, | 71 | Opt_dyn, |
72 | Opt_flock, | ||
72 | Opt_source, | 73 | Opt_source, |
73 | }; | 74 | }; |
74 | 75 | ||
75 | static const struct fs_parameter_spec afs_param_specs[] = { | 76 | static const struct fs_parameter_spec afs_param_specs[] = { |
76 | fsparam_flag ("autocell", Opt_autocell), | 77 | fsparam_flag ("autocell", Opt_autocell), |
77 | fsparam_flag ("dyn", Opt_dyn), | 78 | fsparam_flag ("dyn", Opt_dyn), |
79 | fsparam_enum ("flock", Opt_flock), | ||
78 | fsparam_string("source", Opt_source), | 80 | fsparam_string("source", Opt_source), |
79 | {} | 81 | {} |
80 | }; | 82 | }; |
81 | 83 | ||
84 | static const struct fs_parameter_enum afs_param_enums[] = { | ||
85 | { Opt_flock, "local", afs_flock_mode_local }, | ||
86 | { Opt_flock, "openafs", afs_flock_mode_openafs }, | ||
87 | { Opt_flock, "strict", afs_flock_mode_strict }, | ||
88 | { Opt_flock, "write", afs_flock_mode_write }, | ||
89 | {} | ||
90 | }; | ||
91 | |||
82 | static const struct fs_parameter_description afs_fs_parameters = { | 92 | static const struct fs_parameter_description afs_fs_parameters = { |
83 | .name = "kAFS", | 93 | .name = "kAFS", |
84 | .specs = afs_param_specs, | 94 | .specs = afs_param_specs, |
95 | .enums = afs_param_enums, | ||
85 | }; | 96 | }; |
86 | 97 | ||
87 | /* | 98 | /* |
@@ -184,11 +195,22 @@ static int afs_show_devname(struct seq_file *m, struct dentry *root) | |||
184 | static int afs_show_options(struct seq_file *m, struct dentry *root) | 195 | static int afs_show_options(struct seq_file *m, struct dentry *root) |
185 | { | 196 | { |
186 | struct afs_super_info *as = AFS_FS_S(root->d_sb); | 197 | struct afs_super_info *as = AFS_FS_S(root->d_sb); |
198 | const char *p = NULL; | ||
187 | 199 | ||
188 | if (as->dyn_root) | 200 | if (as->dyn_root) |
189 | seq_puts(m, ",dyn"); | 201 | seq_puts(m, ",dyn"); |
190 | if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags)) | 202 | if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags)) |
191 | seq_puts(m, ",autocell"); | 203 | seq_puts(m, ",autocell"); |
204 | switch (as->flock_mode) { | ||
205 | case afs_flock_mode_unset: break; | ||
206 | case afs_flock_mode_local: p = "local"; break; | ||
207 | case afs_flock_mode_openafs: p = "openafs"; break; | ||
208 | case afs_flock_mode_strict: p = "strict"; break; | ||
209 | case afs_flock_mode_write: p = "write"; break; | ||
210 | } | ||
211 | if (p) | ||
212 | seq_printf(m, ",flock=%s", p); | ||
213 | |||
192 | return 0; | 214 | return 0; |
193 | } | 215 | } |
194 | 216 | ||
@@ -317,6 +339,10 @@ static int afs_parse_param(struct fs_context *fc, struct fs_parameter *param) | |||
317 | ctx->dyn_root = true; | 339 | ctx->dyn_root = true; |
318 | break; | 340 | break; |
319 | 341 | ||
342 | case Opt_flock: | ||
343 | ctx->flock_mode = result.uint_32; | ||
344 | break; | ||
345 | |||
320 | default: | 346 | default: |
321 | return -EINVAL; | 347 | return -EINVAL; |
322 | } | 348 | } |
@@ -429,7 +455,7 @@ static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx) | |||
429 | fid.vnode = 1; | 455 | fid.vnode = 1; |
430 | fid.vnode_hi = 0; | 456 | fid.vnode_hi = 0; |
431 | fid.unique = 1; | 457 | fid.unique = 1; |
432 | inode = afs_iget(sb, ctx->key, &fid, NULL, NULL, NULL); | 458 | inode = afs_iget(sb, ctx->key, &fid, NULL, NULL, NULL, NULL); |
433 | } | 459 | } |
434 | 460 | ||
435 | if (IS_ERR(inode)) | 461 | if (IS_ERR(inode)) |
@@ -468,6 +494,7 @@ static struct afs_super_info *afs_alloc_sbi(struct fs_context *fc) | |||
468 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); | 494 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); |
469 | if (as) { | 495 | if (as) { |
470 | as->net_ns = get_net(fc->net_ns); | 496 | as->net_ns = get_net(fc->net_ns); |
497 | as->flock_mode = ctx->flock_mode; | ||
471 | if (ctx->dyn_root) { | 498 | if (ctx->dyn_root) { |
472 | as->dyn_root = true; | 499 | as->dyn_root = true; |
473 | } else { | 500 | } else { |
@@ -552,6 +579,7 @@ static int afs_get_tree(struct fs_context *fc) | |||
552 | } | 579 | } |
553 | 580 | ||
554 | fc->root = dget(sb->s_root); | 581 | fc->root = dget(sb->s_root); |
582 | trace_afs_get_tree(as->cell, as->volume); | ||
555 | _leave(" = 0 [%p]", sb); | 583 | _leave(" = 0 [%p]", sb); |
556 | return 0; | 584 | return 0; |
557 | 585 | ||
@@ -658,6 +686,8 @@ static struct inode *afs_alloc_inode(struct super_block *sb) | |||
658 | vnode->cb_type = 0; | 686 | vnode->cb_type = 0; |
659 | vnode->lock_state = AFS_VNODE_LOCK_NONE; | 687 | vnode->lock_state = AFS_VNODE_LOCK_NONE; |
660 | 688 | ||
689 | init_rwsem(&vnode->rmdir_lock); | ||
690 | |||
661 | _leave(" = %p", &vnode->vfs_inode); | 691 | _leave(" = %p", &vnode->vfs_inode); |
662 | return &vnode->vfs_inode; | 692 | return &vnode->vfs_inode; |
663 | } | 693 | } |
diff --git a/fs/afs/vl_probe.c b/fs/afs/vl_probe.c index f402ee8171a1..b05e0de04f42 100644 --- a/fs/afs/vl_probe.c +++ b/fs/afs/vl_probe.c | |||
@@ -141,8 +141,8 @@ static bool afs_do_probe_vlserver(struct afs_net *net, | |||
141 | struct afs_addr_cursor ac = { | 141 | struct afs_addr_cursor ac = { |
142 | .index = 0, | 142 | .index = 0, |
143 | }; | 143 | }; |
144 | struct afs_call *call; | ||
144 | bool in_progress = false; | 145 | bool in_progress = false; |
145 | int err; | ||
146 | 146 | ||
147 | _enter("%s", server->name); | 147 | _enter("%s", server->name); |
148 | 148 | ||
@@ -156,12 +156,14 @@ static bool afs_do_probe_vlserver(struct afs_net *net, | |||
156 | server->probe.rtt = UINT_MAX; | 156 | server->probe.rtt = UINT_MAX; |
157 | 157 | ||
158 | for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) { | 158 | for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) { |
159 | err = afs_vl_get_capabilities(net, &ac, key, server, | 159 | call = afs_vl_get_capabilities(net, &ac, key, server, |
160 | server_index, true); | 160 | server_index); |
161 | if (err == -EINPROGRESS) | 161 | if (!IS_ERR(call)) { |
162 | afs_put_call(call); | ||
162 | in_progress = true; | 163 | in_progress = true; |
163 | else | 164 | } else { |
164 | afs_prioritise_error(_e, err, ac.abort_code); | 165 | afs_prioritise_error(_e, PTR_ERR(call), ac.abort_code); |
166 | } | ||
165 | } | 167 | } |
166 | 168 | ||
167 | if (!in_progress) | 169 | if (!in_progress) |
diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c index b0175b3ef0e8..dd9ba4e96fb3 100644 --- a/fs/afs/vlclient.c +++ b/fs/afs/vlclient.c | |||
@@ -167,7 +167,8 @@ struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc, | |||
167 | memset((void *)bp + volnamesz, 0, padsz); | 167 | memset((void *)bp + volnamesz, 0, padsz); |
168 | 168 | ||
169 | trace_afs_make_vl_call(call); | 169 | trace_afs_make_vl_call(call); |
170 | return (struct afs_vldb_entry *)afs_make_call(&vc->ac, call, GFP_KERNEL, false); | 170 | afs_make_call(&vc->ac, call, GFP_KERNEL); |
171 | return (struct afs_vldb_entry *)afs_wait_for_call_to_complete(call, &vc->ac); | ||
171 | } | 172 | } |
172 | 173 | ||
173 | /* | 174 | /* |
@@ -306,7 +307,8 @@ struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc, | |||
306 | r->uuid.node[i] = htonl(u->node[i]); | 307 | r->uuid.node[i] = htonl(u->node[i]); |
307 | 308 | ||
308 | trace_afs_make_vl_call(call); | 309 | trace_afs_make_vl_call(call); |
309 | return (struct afs_addr_list *)afs_make_call(&vc->ac, call, GFP_KERNEL, false); | 310 | afs_make_call(&vc->ac, call, GFP_KERNEL); |
311 | return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac); | ||
310 | } | 312 | } |
311 | 313 | ||
312 | /* | 314 | /* |
@@ -380,12 +382,11 @@ static const struct afs_call_type afs_RXVLGetCapabilities = { | |||
380 | * We use this to probe for service upgrade to determine what the server at the | 382 | * We use this to probe for service upgrade to determine what the server at the |
381 | * other end supports. | 383 | * other end supports. |
382 | */ | 384 | */ |
383 | int afs_vl_get_capabilities(struct afs_net *net, | 385 | struct afs_call *afs_vl_get_capabilities(struct afs_net *net, |
384 | struct afs_addr_cursor *ac, | 386 | struct afs_addr_cursor *ac, |
385 | struct key *key, | 387 | struct key *key, |
386 | struct afs_vlserver *server, | 388 | struct afs_vlserver *server, |
387 | unsigned int server_index, | 389 | unsigned int server_index) |
388 | bool async) | ||
389 | { | 390 | { |
390 | struct afs_call *call; | 391 | struct afs_call *call; |
391 | __be32 *bp; | 392 | __be32 *bp; |
@@ -394,13 +395,14 @@ int afs_vl_get_capabilities(struct afs_net *net, | |||
394 | 395 | ||
395 | call = afs_alloc_flat_call(net, &afs_RXVLGetCapabilities, 1 * 4, 16 * 4); | 396 | call = afs_alloc_flat_call(net, &afs_RXVLGetCapabilities, 1 * 4, 16 * 4); |
396 | if (!call) | 397 | if (!call) |
397 | return -ENOMEM; | 398 | return ERR_PTR(-ENOMEM); |
398 | 399 | ||
399 | call->key = key; | 400 | call->key = key; |
400 | call->reply[0] = afs_get_vlserver(server); | 401 | call->reply[0] = afs_get_vlserver(server); |
401 | call->reply[1] = (void *)(long)server_index; | 402 | call->reply[1] = (void *)(long)server_index; |
402 | call->upgrade = true; | 403 | call->upgrade = true; |
403 | call->want_reply_time = true; | 404 | call->want_reply_time = true; |
405 | call->async = true; | ||
404 | 406 | ||
405 | /* marshall the parameters */ | 407 | /* marshall the parameters */ |
406 | bp = call->request; | 408 | bp = call->request; |
@@ -408,7 +410,8 @@ int afs_vl_get_capabilities(struct afs_net *net, | |||
408 | 410 | ||
409 | /* Can't take a ref on server */ | 411 | /* Can't take a ref on server */ |
410 | trace_afs_make_vl_call(call); | 412 | trace_afs_make_vl_call(call); |
411 | return afs_make_call(ac, call, GFP_KERNEL, async); | 413 | afs_make_call(ac, call, GFP_KERNEL); |
414 | return call; | ||
412 | } | 415 | } |
413 | 416 | ||
414 | /* | 417 | /* |
@@ -651,5 +654,6 @@ struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc, | |||
651 | memcpy(bp, uuid, sizeof(*uuid)); /* Type opr_uuid */ | 654 | memcpy(bp, uuid, sizeof(*uuid)); /* Type opr_uuid */ |
652 | 655 | ||
653 | trace_afs_make_vl_call(call); | 656 | trace_afs_make_vl_call(call); |
654 | return (struct afs_addr_list *)afs_make_call(&vc->ac, call, GFP_KERNEL, false); | 657 | afs_make_call(&vc->ac, call, GFP_KERNEL); |
658 | return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac); | ||
655 | } | 659 | } |
diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c index a2cdf25573e2..c81f85003fc7 100644 --- a/fs/afs/xattr.c +++ b/fs/afs/xattr.c | |||
@@ -16,9 +16,14 @@ | |||
16 | #include "internal.h" | 16 | #include "internal.h" |
17 | 17 | ||
18 | static const char afs_xattr_list[] = | 18 | static const char afs_xattr_list[] = |
19 | "afs.acl\0" | ||
19 | "afs.cell\0" | 20 | "afs.cell\0" |
20 | "afs.fid\0" | 21 | "afs.fid\0" |
21 | "afs.volume"; | 22 | "afs.volume\0" |
23 | "afs.yfs.acl\0" | ||
24 | "afs.yfs.acl_inherited\0" | ||
25 | "afs.yfs.acl_num_cleaned\0" | ||
26 | "afs.yfs.vol_acl"; | ||
22 | 27 | ||
23 | /* | 28 | /* |
24 | * Retrieve a list of the supported xattrs. | 29 | * Retrieve a list of the supported xattrs. |
@@ -34,6 +39,248 @@ ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
34 | } | 39 | } |
35 | 40 | ||
36 | /* | 41 | /* |
42 | * Get a file's ACL. | ||
43 | */ | ||
44 | static int afs_xattr_get_acl(const struct xattr_handler *handler, | ||
45 | struct dentry *dentry, | ||
46 | struct inode *inode, const char *name, | ||
47 | void *buffer, size_t size) | ||
48 | { | ||
49 | struct afs_fs_cursor fc; | ||
50 | struct afs_vnode *vnode = AFS_FS_I(inode); | ||
51 | struct afs_acl *acl = NULL; | ||
52 | struct key *key; | ||
53 | int ret; | ||
54 | |||
55 | key = afs_request_key(vnode->volume->cell); | ||
56 | if (IS_ERR(key)) | ||
57 | return PTR_ERR(key); | ||
58 | |||
59 | ret = -ERESTARTSYS; | ||
60 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | ||
61 | while (afs_select_fileserver(&fc)) { | ||
62 | fc.cb_break = afs_calc_vnode_cb_break(vnode); | ||
63 | acl = afs_fs_fetch_acl(&fc); | ||
64 | } | ||
65 | |||
66 | afs_check_for_remote_deletion(&fc, fc.vnode); | ||
67 | afs_vnode_commit_status(&fc, vnode, fc.cb_break); | ||
68 | ret = afs_end_vnode_operation(&fc); | ||
69 | } | ||
70 | |||
71 | if (ret == 0) { | ||
72 | ret = acl->size; | ||
73 | if (size > 0) { | ||
74 | ret = -ERANGE; | ||
75 | if (acl->size > size) | ||
76 | return -ERANGE; | ||
77 | memcpy(buffer, acl->data, acl->size); | ||
78 | ret = acl->size; | ||
79 | } | ||
80 | kfree(acl); | ||
81 | } | ||
82 | |||
83 | key_put(key); | ||
84 | return ret; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Set a file's AFS3 ACL. | ||
89 | */ | ||
90 | static int afs_xattr_set_acl(const struct xattr_handler *handler, | ||
91 | struct dentry *dentry, | ||
92 | struct inode *inode, const char *name, | ||
93 | const void *buffer, size_t size, int flags) | ||
94 | { | ||
95 | struct afs_fs_cursor fc; | ||
96 | struct afs_vnode *vnode = AFS_FS_I(inode); | ||
97 | struct afs_acl *acl = NULL; | ||
98 | struct key *key; | ||
99 | int ret; | ||
100 | |||
101 | if (flags == XATTR_CREATE) | ||
102 | return -EINVAL; | ||
103 | |||
104 | key = afs_request_key(vnode->volume->cell); | ||
105 | if (IS_ERR(key)) | ||
106 | return PTR_ERR(key); | ||
107 | |||
108 | acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); | ||
109 | if (!acl) { | ||
110 | key_put(key); | ||
111 | return -ENOMEM; | ||
112 | } | ||
113 | |||
114 | acl->size = size; | ||
115 | memcpy(acl->data, buffer, size); | ||
116 | |||
117 | ret = -ERESTARTSYS; | ||
118 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | ||
119 | while (afs_select_fileserver(&fc)) { | ||
120 | fc.cb_break = afs_calc_vnode_cb_break(vnode); | ||
121 | afs_fs_store_acl(&fc, acl); | ||
122 | } | ||
123 | |||
124 | afs_check_for_remote_deletion(&fc, fc.vnode); | ||
125 | afs_vnode_commit_status(&fc, vnode, fc.cb_break); | ||
126 | ret = afs_end_vnode_operation(&fc); | ||
127 | } | ||
128 | |||
129 | kfree(acl); | ||
130 | key_put(key); | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static const struct xattr_handler afs_xattr_afs_acl_handler = { | ||
135 | .name = "afs.acl", | ||
136 | .get = afs_xattr_get_acl, | ||
137 | .set = afs_xattr_set_acl, | ||
138 | }; | ||
139 | |||
140 | /* | ||
141 | * Get a file's YFS ACL. | ||
142 | */ | ||
143 | static int afs_xattr_get_yfs(const struct xattr_handler *handler, | ||
144 | struct dentry *dentry, | ||
145 | struct inode *inode, const char *name, | ||
146 | void *buffer, size_t size) | ||
147 | { | ||
148 | struct afs_fs_cursor fc; | ||
149 | struct afs_vnode *vnode = AFS_FS_I(inode); | ||
150 | struct yfs_acl *yacl = NULL; | ||
151 | struct key *key; | ||
152 | unsigned int flags = 0; | ||
153 | char buf[16], *data; | ||
154 | int which = 0, dsize, ret; | ||
155 | |||
156 | if (strcmp(name, "acl") == 0) | ||
157 | which = 0; | ||
158 | else if (strcmp(name, "acl_inherited") == 0) | ||
159 | which = 1; | ||
160 | else if (strcmp(name, "acl_num_cleaned") == 0) | ||
161 | which = 2; | ||
162 | else if (strcmp(name, "vol_acl") == 0) | ||
163 | which = 3; | ||
164 | else | ||
165 | return -EOPNOTSUPP; | ||
166 | |||
167 | if (which == 0) | ||
168 | flags |= YFS_ACL_WANT_ACL; | ||
169 | else if (which == 3) | ||
170 | flags |= YFS_ACL_WANT_VOL_ACL; | ||
171 | |||
172 | key = afs_request_key(vnode->volume->cell); | ||
173 | if (IS_ERR(key)) | ||
174 | return PTR_ERR(key); | ||
175 | |||
176 | ret = -ERESTARTSYS; | ||
177 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | ||
178 | while (afs_select_fileserver(&fc)) { | ||
179 | fc.cb_break = afs_calc_vnode_cb_break(vnode); | ||
180 | yacl = yfs_fs_fetch_opaque_acl(&fc, flags); | ||
181 | } | ||
182 | |||
183 | afs_check_for_remote_deletion(&fc, fc.vnode); | ||
184 | afs_vnode_commit_status(&fc, vnode, fc.cb_break); | ||
185 | ret = afs_end_vnode_operation(&fc); | ||
186 | } | ||
187 | |||
188 | if (ret == 0) { | ||
189 | switch (which) { | ||
190 | case 0: | ||
191 | data = yacl->acl->data; | ||
192 | dsize = yacl->acl->size; | ||
193 | break; | ||
194 | case 1: | ||
195 | data = buf; | ||
196 | dsize = snprintf(buf, sizeof(buf), "%u", | ||
197 | yacl->inherit_flag); | ||
198 | break; | ||
199 | case 2: | ||
200 | data = buf; | ||
201 | dsize = snprintf(buf, sizeof(buf), "%u", | ||
202 | yacl->num_cleaned); | ||
203 | break; | ||
204 | case 3: | ||
205 | data = yacl->vol_acl->data; | ||
206 | dsize = yacl->vol_acl->size; | ||
207 | break; | ||
208 | default: | ||
209 | ret = -EOPNOTSUPP; | ||
210 | goto out; | ||
211 | } | ||
212 | |||
213 | ret = dsize; | ||
214 | if (size > 0) { | ||
215 | if (dsize > size) { | ||
216 | ret = -ERANGE; | ||
217 | goto out; | ||
218 | } | ||
219 | memcpy(buffer, data, dsize); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | out: | ||
224 | yfs_free_opaque_acl(yacl); | ||
225 | key_put(key); | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * Set a file's YFS ACL. | ||
231 | */ | ||
232 | static int afs_xattr_set_yfs(const struct xattr_handler *handler, | ||
233 | struct dentry *dentry, | ||
234 | struct inode *inode, const char *name, | ||
235 | const void *buffer, size_t size, int flags) | ||
236 | { | ||
237 | struct afs_fs_cursor fc; | ||
238 | struct afs_vnode *vnode = AFS_FS_I(inode); | ||
239 | struct afs_acl *acl = NULL; | ||
240 | struct key *key; | ||
241 | int ret; | ||
242 | |||
243 | if (flags == XATTR_CREATE || | ||
244 | strcmp(name, "acl") != 0) | ||
245 | return -EINVAL; | ||
246 | |||
247 | key = afs_request_key(vnode->volume->cell); | ||
248 | if (IS_ERR(key)) | ||
249 | return PTR_ERR(key); | ||
250 | |||
251 | acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); | ||
252 | if (!acl) { | ||
253 | key_put(key); | ||
254 | return -ENOMEM; | ||
255 | } | ||
256 | |||
257 | acl->size = size; | ||
258 | memcpy(acl->data, buffer, size); | ||
259 | |||
260 | ret = -ERESTARTSYS; | ||
261 | if (afs_begin_vnode_operation(&fc, vnode, key)) { | ||
262 | while (afs_select_fileserver(&fc)) { | ||
263 | fc.cb_break = afs_calc_vnode_cb_break(vnode); | ||
264 | yfs_fs_store_opaque_acl2(&fc, acl); | ||
265 | } | ||
266 | |||
267 | afs_check_for_remote_deletion(&fc, fc.vnode); | ||
268 | afs_vnode_commit_status(&fc, vnode, fc.cb_break); | ||
269 | ret = afs_end_vnode_operation(&fc); | ||
270 | } | ||
271 | |||
272 | kfree(acl); | ||
273 | key_put(key); | ||
274 | return ret; | ||
275 | } | ||
276 | |||
277 | static const struct xattr_handler afs_xattr_yfs_handler = { | ||
278 | .prefix = "afs.yfs.", | ||
279 | .get = afs_xattr_get_yfs, | ||
280 | .set = afs_xattr_set_yfs, | ||
281 | }; | ||
282 | |||
283 | /* | ||
37 | * Get the name of the cell on which a file resides. | 284 | * Get the name of the cell on which a file resides. |
38 | */ | 285 | */ |
39 | static int afs_xattr_get_cell(const struct xattr_handler *handler, | 286 | static int afs_xattr_get_cell(const struct xattr_handler *handler, |
@@ -50,7 +297,7 @@ static int afs_xattr_get_cell(const struct xattr_handler *handler, | |||
50 | return namelen; | 297 | return namelen; |
51 | if (namelen > size) | 298 | if (namelen > size) |
52 | return -ERANGE; | 299 | return -ERANGE; |
53 | memcpy(buffer, cell->name, size); | 300 | memcpy(buffer, cell->name, namelen); |
54 | return namelen; | 301 | return namelen; |
55 | } | 302 | } |
56 | 303 | ||
@@ -69,11 +316,20 @@ static int afs_xattr_get_fid(const struct xattr_handler *handler, | |||
69 | void *buffer, size_t size) | 316 | void *buffer, size_t size) |
70 | { | 317 | { |
71 | struct afs_vnode *vnode = AFS_FS_I(inode); | 318 | struct afs_vnode *vnode = AFS_FS_I(inode); |
72 | char text[8 + 1 + 8 + 1 + 8 + 1]; | 319 | char text[16 + 1 + 24 + 1 + 8 + 1]; |
73 | size_t len; | 320 | size_t len; |
74 | 321 | ||
75 | len = sprintf(text, "%llx:%llx:%x", | 322 | /* The volume ID is 64-bit, the vnode ID is 96-bit and the |
76 | vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); | 323 | * uniquifier is 32-bit. |
324 | */ | ||
325 | len = sprintf(text, "%llx:", vnode->fid.vid); | ||
326 | if (vnode->fid.vnode_hi) | ||
327 | len += sprintf(text + len, "%x%016llx", | ||
328 | vnode->fid.vnode_hi, vnode->fid.vnode); | ||
329 | else | ||
330 | len += sprintf(text + len, "%llx", vnode->fid.vnode); | ||
331 | len += sprintf(text + len, ":%x", vnode->fid.unique); | ||
332 | |||
77 | if (size == 0) | 333 | if (size == 0) |
78 | return len; | 334 | return len; |
79 | if (len > size) | 335 | if (len > size) |
@@ -104,7 +360,7 @@ static int afs_xattr_get_volume(const struct xattr_handler *handler, | |||
104 | return namelen; | 360 | return namelen; |
105 | if (namelen > size) | 361 | if (namelen > size) |
106 | return -ERANGE; | 362 | return -ERANGE; |
107 | memcpy(buffer, volname, size); | 363 | memcpy(buffer, volname, namelen); |
108 | return namelen; | 364 | return namelen; |
109 | } | 365 | } |
110 | 366 | ||
@@ -114,8 +370,10 @@ static const struct xattr_handler afs_xattr_afs_volume_handler = { | |||
114 | }; | 370 | }; |
115 | 371 | ||
116 | const struct xattr_handler *afs_xattr_handlers[] = { | 372 | const struct xattr_handler *afs_xattr_handlers[] = { |
373 | &afs_xattr_afs_acl_handler, | ||
117 | &afs_xattr_afs_cell_handler, | 374 | &afs_xattr_afs_cell_handler, |
118 | &afs_xattr_afs_fid_handler, | 375 | &afs_xattr_afs_fid_handler, |
119 | &afs_xattr_afs_volume_handler, | 376 | &afs_xattr_afs_volume_handler, |
377 | &afs_xattr_yfs_handler, /* afs.yfs. prefix */ | ||
120 | NULL | 378 | NULL |
121 | }; | 379 | }; |
diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c index 871e29f06257..6cf7d161baa1 100644 --- a/fs/afs/yfsclient.c +++ b/fs/afs/yfsclient.c | |||
@@ -519,7 +519,8 @@ int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy | |||
519 | call->cb_break = fc->cb_break; | 519 | call->cb_break = fc->cb_break; |
520 | afs_use_fs_server(call, fc->cbi); | 520 | afs_use_fs_server(call, fc->cbi); |
521 | trace_afs_make_fs_call(call, &vnode->fid); | 521 | trace_afs_make_fs_call(call, &vnode->fid); |
522 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 522 | afs_make_call(&fc->ac, call, GFP_NOFS); |
523 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
523 | } | 524 | } |
524 | 525 | ||
525 | /* | 526 | /* |
@@ -711,7 +712,8 @@ int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req) | |||
711 | call->cb_break = fc->cb_break; | 712 | call->cb_break = fc->cb_break; |
712 | afs_use_fs_server(call, fc->cbi); | 713 | afs_use_fs_server(call, fc->cbi); |
713 | trace_afs_make_fs_call(call, &vnode->fid); | 714 | trace_afs_make_fs_call(call, &vnode->fid); |
714 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 715 | afs_make_call(&fc->ac, call, GFP_NOFS); |
716 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
715 | } | 717 | } |
716 | 718 | ||
717 | /* | 719 | /* |
@@ -810,8 +812,9 @@ int yfs_fs_create_file(struct afs_fs_cursor *fc, | |||
810 | yfs_check_req(call, bp); | 812 | yfs_check_req(call, bp); |
811 | 813 | ||
812 | afs_use_fs_server(call, fc->cbi); | 814 | afs_use_fs_server(call, fc->cbi); |
813 | trace_afs_make_fs_call(call, &vnode->fid); | 815 | trace_afs_make_fs_call1(call, &vnode->fid, name); |
814 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 816 | afs_make_call(&fc->ac, call, GFP_NOFS); |
817 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
815 | } | 818 | } |
816 | 819 | ||
817 | static const struct afs_call_type yfs_RXFSMakeDir = { | 820 | static const struct afs_call_type yfs_RXFSMakeDir = { |
@@ -873,8 +876,9 @@ int yfs_fs_make_dir(struct afs_fs_cursor *fc, | |||
873 | yfs_check_req(call, bp); | 876 | yfs_check_req(call, bp); |
874 | 877 | ||
875 | afs_use_fs_server(call, fc->cbi); | 878 | afs_use_fs_server(call, fc->cbi); |
876 | trace_afs_make_fs_call(call, &vnode->fid); | 879 | trace_afs_make_fs_call1(call, &vnode->fid, name); |
877 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 880 | afs_make_call(&fc->ac, call, GFP_NOFS); |
881 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
878 | } | 882 | } |
879 | 883 | ||
880 | /* | 884 | /* |
@@ -963,8 +967,9 @@ int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode, | |||
963 | yfs_check_req(call, bp); | 967 | yfs_check_req(call, bp); |
964 | 968 | ||
965 | afs_use_fs_server(call, fc->cbi); | 969 | afs_use_fs_server(call, fc->cbi); |
966 | trace_afs_make_fs_call(call, &dvnode->fid); | 970 | trace_afs_make_fs_call1(call, &dvnode->fid, name); |
967 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 971 | afs_make_call(&fc->ac, call, GFP_NOFS); |
972 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
968 | } | 973 | } |
969 | 974 | ||
970 | /* | 975 | /* |
@@ -1050,8 +1055,9 @@ int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode, | |||
1050 | yfs_check_req(call, bp); | 1055 | yfs_check_req(call, bp); |
1051 | 1056 | ||
1052 | afs_use_fs_server(call, fc->cbi); | 1057 | afs_use_fs_server(call, fc->cbi); |
1053 | trace_afs_make_fs_call(call, &dvnode->fid); | 1058 | trace_afs_make_fs_call1(call, &dvnode->fid, name); |
1054 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1059 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1060 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1055 | } | 1061 | } |
1056 | 1062 | ||
1057 | /* | 1063 | /* |
@@ -1135,8 +1141,9 @@ int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, | |||
1135 | yfs_check_req(call, bp); | 1141 | yfs_check_req(call, bp); |
1136 | 1142 | ||
1137 | afs_use_fs_server(call, fc->cbi); | 1143 | afs_use_fs_server(call, fc->cbi); |
1138 | trace_afs_make_fs_call(call, &vnode->fid); | 1144 | trace_afs_make_fs_call1(call, &vnode->fid, name); |
1139 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1145 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1146 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1140 | } | 1147 | } |
1141 | 1148 | ||
1142 | /* | 1149 | /* |
@@ -1231,8 +1238,9 @@ int yfs_fs_symlink(struct afs_fs_cursor *fc, | |||
1231 | yfs_check_req(call, bp); | 1238 | yfs_check_req(call, bp); |
1232 | 1239 | ||
1233 | afs_use_fs_server(call, fc->cbi); | 1240 | afs_use_fs_server(call, fc->cbi); |
1234 | trace_afs_make_fs_call(call, &dvnode->fid); | 1241 | trace_afs_make_fs_call1(call, &dvnode->fid, name); |
1235 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1242 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1243 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1236 | } | 1244 | } |
1237 | 1245 | ||
1238 | /* | 1246 | /* |
@@ -1329,8 +1337,9 @@ int yfs_fs_rename(struct afs_fs_cursor *fc, | |||
1329 | yfs_check_req(call, bp); | 1337 | yfs_check_req(call, bp); |
1330 | 1338 | ||
1331 | afs_use_fs_server(call, fc->cbi); | 1339 | afs_use_fs_server(call, fc->cbi); |
1332 | trace_afs_make_fs_call(call, &orig_dvnode->fid); | 1340 | trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name); |
1333 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1341 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1342 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1334 | } | 1343 | } |
1335 | 1344 | ||
1336 | /* | 1345 | /* |
@@ -1436,7 +1445,8 @@ int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping, | |||
1436 | 1445 | ||
1437 | afs_use_fs_server(call, fc->cbi); | 1446 | afs_use_fs_server(call, fc->cbi); |
1438 | trace_afs_make_fs_call(call, &vnode->fid); | 1447 | trace_afs_make_fs_call(call, &vnode->fid); |
1439 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1448 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1449 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1440 | } | 1450 | } |
1441 | 1451 | ||
1442 | /* | 1452 | /* |
@@ -1524,7 +1534,8 @@ static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr) | |||
1524 | 1534 | ||
1525 | afs_use_fs_server(call, fc->cbi); | 1535 | afs_use_fs_server(call, fc->cbi); |
1526 | trace_afs_make_fs_call(call, &vnode->fid); | 1536 | trace_afs_make_fs_call(call, &vnode->fid); |
1527 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1537 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1538 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1528 | } | 1539 | } |
1529 | 1540 | ||
1530 | /* | 1541 | /* |
@@ -1567,7 +1578,8 @@ int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr) | |||
1567 | 1578 | ||
1568 | afs_use_fs_server(call, fc->cbi); | 1579 | afs_use_fs_server(call, fc->cbi); |
1569 | trace_afs_make_fs_call(call, &vnode->fid); | 1580 | trace_afs_make_fs_call(call, &vnode->fid); |
1570 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1581 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1582 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1571 | } | 1583 | } |
1572 | 1584 | ||
1573 | /* | 1585 | /* |
@@ -1755,13 +1767,15 @@ int yfs_fs_get_volume_status(struct afs_fs_cursor *fc, | |||
1755 | 1767 | ||
1756 | afs_use_fs_server(call, fc->cbi); | 1768 | afs_use_fs_server(call, fc->cbi); |
1757 | trace_afs_make_fs_call(call, &vnode->fid); | 1769 | trace_afs_make_fs_call(call, &vnode->fid); |
1758 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1770 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1771 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1759 | } | 1772 | } |
1760 | 1773 | ||
1761 | /* | 1774 | /* |
1762 | * Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock | 1775 | * Deliver reply data to operations that just return a file status and a volume |
1776 | * sync record. | ||
1763 | */ | 1777 | */ |
1764 | static int yfs_deliver_fs_xxxx_lock(struct afs_call *call) | 1778 | static int yfs_deliver_status_and_volsync(struct afs_call *call) |
1765 | { | 1779 | { |
1766 | struct afs_vnode *vnode = call->reply[0]; | 1780 | struct afs_vnode *vnode = call->reply[0]; |
1767 | const __be32 *bp; | 1781 | const __be32 *bp; |
@@ -1791,7 +1805,8 @@ static int yfs_deliver_fs_xxxx_lock(struct afs_call *call) | |||
1791 | static const struct afs_call_type yfs_RXYFSSetLock = { | 1805 | static const struct afs_call_type yfs_RXYFSSetLock = { |
1792 | .name = "YFS.SetLock", | 1806 | .name = "YFS.SetLock", |
1793 | .op = yfs_FS_SetLock, | 1807 | .op = yfs_FS_SetLock, |
1794 | .deliver = yfs_deliver_fs_xxxx_lock, | 1808 | .deliver = yfs_deliver_status_and_volsync, |
1809 | .done = afs_lock_op_done, | ||
1795 | .destructor = afs_flat_call_destructor, | 1810 | .destructor = afs_flat_call_destructor, |
1796 | }; | 1811 | }; |
1797 | 1812 | ||
@@ -1801,7 +1816,8 @@ static const struct afs_call_type yfs_RXYFSSetLock = { | |||
1801 | static const struct afs_call_type yfs_RXYFSExtendLock = { | 1816 | static const struct afs_call_type yfs_RXYFSExtendLock = { |
1802 | .name = "YFS.ExtendLock", | 1817 | .name = "YFS.ExtendLock", |
1803 | .op = yfs_FS_ExtendLock, | 1818 | .op = yfs_FS_ExtendLock, |
1804 | .deliver = yfs_deliver_fs_xxxx_lock, | 1819 | .deliver = yfs_deliver_status_and_volsync, |
1820 | .done = afs_lock_op_done, | ||
1805 | .destructor = afs_flat_call_destructor, | 1821 | .destructor = afs_flat_call_destructor, |
1806 | }; | 1822 | }; |
1807 | 1823 | ||
@@ -1811,7 +1827,7 @@ static const struct afs_call_type yfs_RXYFSExtendLock = { | |||
1811 | static const struct afs_call_type yfs_RXYFSReleaseLock = { | 1827 | static const struct afs_call_type yfs_RXYFSReleaseLock = { |
1812 | .name = "YFS.ReleaseLock", | 1828 | .name = "YFS.ReleaseLock", |
1813 | .op = yfs_FS_ReleaseLock, | 1829 | .op = yfs_FS_ReleaseLock, |
1814 | .deliver = yfs_deliver_fs_xxxx_lock, | 1830 | .deliver = yfs_deliver_status_and_volsync, |
1815 | .destructor = afs_flat_call_destructor, | 1831 | .destructor = afs_flat_call_destructor, |
1816 | }; | 1832 | }; |
1817 | 1833 | ||
@@ -1838,6 +1854,7 @@ int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) | |||
1838 | 1854 | ||
1839 | call->key = fc->key; | 1855 | call->key = fc->key; |
1840 | call->reply[0] = vnode; | 1856 | call->reply[0] = vnode; |
1857 | call->want_reply_time = true; | ||
1841 | 1858 | ||
1842 | /* marshall the parameters */ | 1859 | /* marshall the parameters */ |
1843 | bp = call->request; | 1860 | bp = call->request; |
@@ -1848,8 +1865,9 @@ int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) | |||
1848 | yfs_check_req(call, bp); | 1865 | yfs_check_req(call, bp); |
1849 | 1866 | ||
1850 | afs_use_fs_server(call, fc->cbi); | 1867 | afs_use_fs_server(call, fc->cbi); |
1851 | trace_afs_make_fs_call(call, &vnode->fid); | 1868 | trace_afs_make_fs_calli(call, &vnode->fid, type); |
1852 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1869 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1870 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1853 | } | 1871 | } |
1854 | 1872 | ||
1855 | /* | 1873 | /* |
@@ -1874,6 +1892,7 @@ int yfs_fs_extend_lock(struct afs_fs_cursor *fc) | |||
1874 | 1892 | ||
1875 | call->key = fc->key; | 1893 | call->key = fc->key; |
1876 | call->reply[0] = vnode; | 1894 | call->reply[0] = vnode; |
1895 | call->want_reply_time = true; | ||
1877 | 1896 | ||
1878 | /* marshall the parameters */ | 1897 | /* marshall the parameters */ |
1879 | bp = call->request; | 1898 | bp = call->request; |
@@ -1884,7 +1903,8 @@ int yfs_fs_extend_lock(struct afs_fs_cursor *fc) | |||
1884 | 1903 | ||
1885 | afs_use_fs_server(call, fc->cbi); | 1904 | afs_use_fs_server(call, fc->cbi); |
1886 | trace_afs_make_fs_call(call, &vnode->fid); | 1905 | trace_afs_make_fs_call(call, &vnode->fid); |
1887 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1906 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1907 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1888 | } | 1908 | } |
1889 | 1909 | ||
1890 | /* | 1910 | /* |
@@ -1919,7 +1939,8 @@ int yfs_fs_release_lock(struct afs_fs_cursor *fc) | |||
1919 | 1939 | ||
1920 | afs_use_fs_server(call, fc->cbi); | 1940 | afs_use_fs_server(call, fc->cbi); |
1921 | trace_afs_make_fs_call(call, &vnode->fid); | 1941 | trace_afs_make_fs_call(call, &vnode->fid); |
1922 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 1942 | afs_make_call(&fc->ac, call, GFP_NOFS); |
1943 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
1923 | } | 1944 | } |
1924 | 1945 | ||
1925 | /* | 1946 | /* |
@@ -2007,7 +2028,8 @@ int yfs_fs_fetch_status(struct afs_fs_cursor *fc, | |||
2007 | call->cb_break = fc->cb_break; | 2028 | call->cb_break = fc->cb_break; |
2008 | afs_use_fs_server(call, fc->cbi); | 2029 | afs_use_fs_server(call, fc->cbi); |
2009 | trace_afs_make_fs_call(call, fid); | 2030 | trace_afs_make_fs_call(call, fid); |
2010 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 2031 | afs_make_call(&fc->ac, call, GFP_NOFS); |
2032 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
2011 | } | 2033 | } |
2012 | 2034 | ||
2013 | /* | 2035 | /* |
@@ -2190,5 +2212,250 @@ int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc, | |||
2190 | call->cb_break = fc->cb_break; | 2212 | call->cb_break = fc->cb_break; |
2191 | afs_use_fs_server(call, fc->cbi); | 2213 | afs_use_fs_server(call, fc->cbi); |
2192 | trace_afs_make_fs_call(call, &fids[0]); | 2214 | trace_afs_make_fs_call(call, &fids[0]); |
2193 | return afs_make_call(&fc->ac, call, GFP_NOFS, false); | 2215 | afs_make_call(&fc->ac, call, GFP_NOFS); |
2216 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
2217 | } | ||
2218 | |||
2219 | /* | ||
2220 | * Deliver reply data to an YFS.FetchOpaqueACL. | ||
2221 | */ | ||
2222 | static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call) | ||
2223 | { | ||
2224 | struct afs_volsync *volsync = call->reply[2]; | ||
2225 | struct afs_vnode *vnode = call->reply[1]; | ||
2226 | struct yfs_acl *yacl = call->reply[0]; | ||
2227 | struct afs_acl *acl; | ||
2228 | const __be32 *bp; | ||
2229 | unsigned int size; | ||
2230 | int ret; | ||
2231 | |||
2232 | _enter("{%u}", call->unmarshall); | ||
2233 | |||
2234 | switch (call->unmarshall) { | ||
2235 | case 0: | ||
2236 | afs_extract_to_tmp(call); | ||
2237 | call->unmarshall++; | ||
2238 | |||
2239 | /* Extract the file ACL length */ | ||
2240 | case 1: | ||
2241 | ret = afs_extract_data(call, true); | ||
2242 | if (ret < 0) | ||
2243 | return ret; | ||
2244 | |||
2245 | size = call->count2 = ntohl(call->tmp); | ||
2246 | size = round_up(size, 4); | ||
2247 | |||
2248 | if (yacl->flags & YFS_ACL_WANT_ACL) { | ||
2249 | acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL); | ||
2250 | if (!acl) | ||
2251 | return -ENOMEM; | ||
2252 | yacl->acl = acl; | ||
2253 | acl->size = call->count2; | ||
2254 | afs_extract_begin(call, acl->data, size); | ||
2255 | } else { | ||
2256 | iov_iter_discard(&call->iter, READ, size); | ||
2257 | } | ||
2258 | call->unmarshall++; | ||
2259 | |||
2260 | /* Extract the file ACL */ | ||
2261 | case 2: | ||
2262 | ret = afs_extract_data(call, true); | ||
2263 | if (ret < 0) | ||
2264 | return ret; | ||
2265 | |||
2266 | afs_extract_to_tmp(call); | ||
2267 | call->unmarshall++; | ||
2268 | |||
2269 | /* Extract the volume ACL length */ | ||
2270 | case 3: | ||
2271 | ret = afs_extract_data(call, true); | ||
2272 | if (ret < 0) | ||
2273 | return ret; | ||
2274 | |||
2275 | size = call->count2 = ntohl(call->tmp); | ||
2276 | size = round_up(size, 4); | ||
2277 | |||
2278 | if (yacl->flags & YFS_ACL_WANT_VOL_ACL) { | ||
2279 | acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL); | ||
2280 | if (!acl) | ||
2281 | return -ENOMEM; | ||
2282 | yacl->vol_acl = acl; | ||
2283 | acl->size = call->count2; | ||
2284 | afs_extract_begin(call, acl->data, size); | ||
2285 | } else { | ||
2286 | iov_iter_discard(&call->iter, READ, size); | ||
2287 | } | ||
2288 | call->unmarshall++; | ||
2289 | |||
2290 | /* Extract the volume ACL */ | ||
2291 | case 4: | ||
2292 | ret = afs_extract_data(call, true); | ||
2293 | if (ret < 0) | ||
2294 | return ret; | ||
2295 | |||
2296 | afs_extract_to_buf(call, | ||
2297 | sizeof(__be32) * 2 + | ||
2298 | sizeof(struct yfs_xdr_YFSFetchStatus) + | ||
2299 | sizeof(struct yfs_xdr_YFSVolSync)); | ||
2300 | call->unmarshall++; | ||
2301 | |||
2302 | /* extract the metadata */ | ||
2303 | case 5: | ||
2304 | ret = afs_extract_data(call, false); | ||
2305 | if (ret < 0) | ||
2306 | return ret; | ||
2307 | |||
2308 | bp = call->buffer; | ||
2309 | yacl->inherit_flag = ntohl(*bp++); | ||
2310 | yacl->num_cleaned = ntohl(*bp++); | ||
2311 | ret = yfs_decode_status(call, &bp, &vnode->status, vnode, | ||
2312 | &call->expected_version, NULL); | ||
2313 | if (ret < 0) | ||
2314 | return ret; | ||
2315 | xdr_decode_YFSVolSync(&bp, volsync); | ||
2316 | |||
2317 | call->unmarshall++; | ||
2318 | |||
2319 | case 6: | ||
2320 | break; | ||
2321 | } | ||
2322 | |||
2323 | _leave(" = 0 [done]"); | ||
2324 | return 0; | ||
2325 | } | ||
2326 | |||
2327 | void yfs_free_opaque_acl(struct yfs_acl *yacl) | ||
2328 | { | ||
2329 | if (yacl) { | ||
2330 | kfree(yacl->acl); | ||
2331 | kfree(yacl->vol_acl); | ||
2332 | kfree(yacl); | ||
2333 | } | ||
2334 | } | ||
2335 | |||
2336 | static void yfs_destroy_fs_fetch_opaque_acl(struct afs_call *call) | ||
2337 | { | ||
2338 | yfs_free_opaque_acl(call->reply[0]); | ||
2339 | afs_flat_call_destructor(call); | ||
2340 | } | ||
2341 | |||
2342 | /* | ||
2343 | * YFS.FetchOpaqueACL operation type | ||
2344 | */ | ||
2345 | static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = { | ||
2346 | .name = "YFS.FetchOpaqueACL", | ||
2347 | .op = yfs_FS_FetchOpaqueACL, | ||
2348 | .deliver = yfs_deliver_fs_fetch_opaque_acl, | ||
2349 | .destructor = yfs_destroy_fs_fetch_opaque_acl, | ||
2350 | }; | ||
2351 | |||
2352 | /* | ||
2353 | * Fetch the YFS advanced ACLs for a file. | ||
2354 | */ | ||
2355 | struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc, | ||
2356 | unsigned int flags) | ||
2357 | { | ||
2358 | struct afs_vnode *vnode = fc->vnode; | ||
2359 | struct afs_call *call; | ||
2360 | struct yfs_acl *yacl; | ||
2361 | struct afs_net *net = afs_v2net(vnode); | ||
2362 | __be32 *bp; | ||
2363 | |||
2364 | _enter(",%x,{%llx:%llu},,", | ||
2365 | key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); | ||
2366 | |||
2367 | call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL, | ||
2368 | sizeof(__be32) * 2 + | ||
2369 | sizeof(struct yfs_xdr_YFSFid), | ||
2370 | sizeof(__be32) * 2 + | ||
2371 | sizeof(struct yfs_xdr_YFSFetchStatus) + | ||
2372 | sizeof(struct yfs_xdr_YFSVolSync)); | ||
2373 | if (!call) | ||
2374 | goto nomem; | ||
2375 | |||
2376 | yacl = kzalloc(sizeof(struct yfs_acl), GFP_KERNEL); | ||
2377 | if (!yacl) | ||
2378 | goto nomem_call; | ||
2379 | |||
2380 | yacl->flags = flags; | ||
2381 | call->key = fc->key; | ||
2382 | call->reply[0] = yacl; | ||
2383 | call->reply[1] = vnode; | ||
2384 | call->reply[2] = NULL; /* volsync */ | ||
2385 | call->ret_reply0 = true; | ||
2386 | |||
2387 | /* marshall the parameters */ | ||
2388 | bp = call->request; | ||
2389 | bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL); | ||
2390 | bp = xdr_encode_u32(bp, 0); /* RPC flags */ | ||
2391 | bp = xdr_encode_YFSFid(bp, &vnode->fid); | ||
2392 | yfs_check_req(call, bp); | ||
2393 | |||
2394 | call->cb_break = fc->cb_break; | ||
2395 | afs_use_fs_server(call, fc->cbi); | ||
2396 | trace_afs_make_fs_call(call, &vnode->fid); | ||
2397 | afs_make_call(&fc->ac, call, GFP_KERNEL); | ||
2398 | return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac); | ||
2399 | |||
2400 | nomem_call: | ||
2401 | afs_put_call(call); | ||
2402 | nomem: | ||
2403 | fc->ac.error = -ENOMEM; | ||
2404 | return ERR_PTR(-ENOMEM); | ||
2405 | } | ||
2406 | |||
2407 | /* | ||
2408 | * YFS.StoreOpaqueACL2 operation type | ||
2409 | */ | ||
2410 | static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = { | ||
2411 | .name = "YFS.StoreOpaqueACL2", | ||
2412 | .op = yfs_FS_StoreOpaqueACL2, | ||
2413 | .deliver = yfs_deliver_status_and_volsync, | ||
2414 | .destructor = afs_flat_call_destructor, | ||
2415 | }; | ||
2416 | |||
2417 | /* | ||
2418 | * Fetch the YFS ACL for a file. | ||
2419 | */ | ||
2420 | int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl) | ||
2421 | { | ||
2422 | struct afs_vnode *vnode = fc->vnode; | ||
2423 | struct afs_call *call; | ||
2424 | struct afs_net *net = afs_v2net(vnode); | ||
2425 | size_t size; | ||
2426 | __be32 *bp; | ||
2427 | |||
2428 | _enter(",%x,{%llx:%llu},,", | ||
2429 | key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); | ||
2430 | |||
2431 | size = round_up(acl->size, 4); | ||
2432 | call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus, | ||
2433 | sizeof(__be32) * 2 + | ||
2434 | sizeof(struct yfs_xdr_YFSFid) + | ||
2435 | sizeof(__be32) + size, | ||
2436 | sizeof(struct yfs_xdr_YFSFetchStatus) + | ||
2437 | sizeof(struct yfs_xdr_YFSVolSync)); | ||
2438 | if (!call) { | ||
2439 | fc->ac.error = -ENOMEM; | ||
2440 | return -ENOMEM; | ||
2441 | } | ||
2442 | |||
2443 | call->key = fc->key; | ||
2444 | call->reply[0] = vnode; | ||
2445 | call->reply[2] = NULL; /* volsync */ | ||
2446 | |||
2447 | /* marshall the parameters */ | ||
2448 | bp = call->request; | ||
2449 | bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2); | ||
2450 | bp = xdr_encode_u32(bp, 0); /* RPC flags */ | ||
2451 | bp = xdr_encode_YFSFid(bp, &vnode->fid); | ||
2452 | bp = xdr_encode_u32(bp, acl->size); | ||
2453 | memcpy(bp, acl->data, acl->size); | ||
2454 | if (acl->size != size) | ||
2455 | memset((void *)bp + acl->size, 0, size - acl->size); | ||
2456 | yfs_check_req(call, bp); | ||
2457 | |||
2458 | trace_afs_make_fs_call(call, &vnode->fid); | ||
2459 | afs_make_call(&fc->ac, call, GFP_KERNEL); | ||
2460 | return afs_wait_for_call_to_complete(call, &fc->ac); | ||
2194 | } | 2461 | } |