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()
This commit is contained in:
Linus Torvalds
2019-05-07 20:51:58 -07:00
18 changed files with 2142 additions and 378 deletions

View File

@@ -468,7 +468,9 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy
call->cb_break = fc->cb_break;
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -662,7 +664,8 @@ static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
call->cb_break = fc->cb_break;
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -709,7 +712,8 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
call->cb_break = fc->cb_break;
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -828,14 +832,16 @@ int afs_fs_create(struct afs_fs_cursor *fc,
*bp++ = 0; /* segment size */
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
trace_afs_make_fs_call1(call, &vnode->fid, name);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
* deliver reply data to an FS.RemoveFile or FS.RemoveDir
* Deliver reply data to any operation that returns file status and volume
* sync.
*/
static int afs_deliver_fs_remove(struct afs_call *call)
static int afs_deliver_fs_status_and_vol(struct afs_call *call)
{
struct afs_vnode *vnode = call->reply[0];
const __be32 *bp;
@@ -865,14 +871,14 @@ static int afs_deliver_fs_remove(struct afs_call *call)
static const struct afs_call_type afs_RXFSRemoveFile = {
.name = "FS.RemoveFile",
.op = afs_FS_RemoveFile,
.deliver = afs_deliver_fs_remove,
.deliver = afs_deliver_fs_status_and_vol,
.destructor = afs_flat_call_destructor,
};
static const struct afs_call_type afs_RXFSRemoveDir = {
.name = "FS.RemoveDir",
.op = afs_FS_RemoveDir,
.deliver = afs_deliver_fs_remove,
.deliver = afs_deliver_fs_status_and_vol,
.destructor = afs_flat_call_destructor,
};
@@ -923,8 +929,9 @@ int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
}
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &dvnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
trace_afs_make_fs_call1(call, &dvnode->fid, name);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1015,8 +1022,9 @@ int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
*bp++ = htonl(vnode->fid.unique);
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
trace_afs_make_fs_call1(call, &vnode->fid, name);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1129,8 +1137,9 @@ int afs_fs_symlink(struct afs_fs_cursor *fc,
*bp++ = 0; /* segment size */
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
trace_afs_make_fs_call1(call, &vnode->fid, name);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1247,8 +1256,9 @@ int afs_fs_rename(struct afs_fs_cursor *fc,
}
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &orig_dvnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1352,7 +1362,8 @@ static int afs_fs_store_data64(struct afs_fs_cursor *fc,
*bp++ = htonl((u32) i_size);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1428,7 +1439,8 @@ int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1526,7 +1538,8 @@ static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr)
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1572,7 +1585,8 @@ static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1616,7 +1630,8 @@ int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1800,7 +1815,8 @@ int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1832,6 +1848,7 @@ static const struct afs_call_type afs_RXFSSetLock = {
.name = "FS.SetLock",
.op = afs_FS_SetLock,
.deliver = afs_deliver_fs_xxxx_lock,
.done = afs_lock_op_done,
.destructor = afs_flat_call_destructor,
};
@@ -1842,6 +1859,7 @@ static const struct afs_call_type afs_RXFSExtendLock = {
.name = "FS.ExtendLock",
.op = afs_FS_ExtendLock,
.deliver = afs_deliver_fs_xxxx_lock,
.done = afs_lock_op_done,
.destructor = afs_flat_call_destructor,
};
@@ -1876,6 +1894,7 @@ int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
call->key = fc->key;
call->reply[0] = vnode;
call->want_reply_time = true;
/* marshall the parameters */
bp = call->request;
@@ -1886,8 +1905,9 @@ int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
*bp++ = htonl(type);
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
trace_afs_make_fs_calli(call, &vnode->fid, type);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1911,6 +1931,7 @@ int afs_fs_extend_lock(struct afs_fs_cursor *fc)
call->key = fc->key;
call->reply[0] = vnode;
call->want_reply_time = true;
/* marshall the parameters */
bp = call->request;
@@ -1921,7 +1942,8 @@ int afs_fs_extend_lock(struct afs_fs_cursor *fc)
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -1955,7 +1977,8 @@ int afs_fs_release_lock(struct afs_fs_cursor *fc)
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -2000,7 +2023,8 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net,
*bp++ = htonl(FSGIVEUPALLCALLBACKS);
/* Can't take a ref on server */
return afs_make_call(ac, call, GFP_NOFS, false);
afs_make_call(ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, ac);
}
/*
@@ -2070,12 +2094,11 @@ static const struct afs_call_type afs_RXFSGetCapabilities = {
* Probe a fileserver for the capabilities that it supports. This can
* return up to 196 words.
*/
int afs_fs_get_capabilities(struct afs_net *net,
struct afs_server *server,
struct afs_addr_cursor *ac,
struct key *key,
unsigned int server_index,
bool async)
struct afs_call *afs_fs_get_capabilities(struct afs_net *net,
struct afs_server *server,
struct afs_addr_cursor *ac,
struct key *key,
unsigned int server_index)
{
struct afs_call *call;
__be32 *bp;
@@ -2084,13 +2107,14 @@ int afs_fs_get_capabilities(struct afs_net *net,
call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);
if (!call)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
call->key = key;
call->reply[0] = afs_get_server(server);
call->reply[1] = (void *)(long)server_index;
call->upgrade = true;
call->want_reply_time = true;
call->async = true;
/* marshall the parameters */
bp = call->request;
@@ -2098,7 +2122,8 @@ int afs_fs_get_capabilities(struct afs_net *net,
/* Can't take a ref on server */
trace_afs_make_fs_call(call, NULL);
return afs_make_call(ac, call, GFP_NOFS, async);
afs_make_call(ac, call, GFP_NOFS);
return call;
}
/*
@@ -2185,7 +2210,8 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc,
call->cb_break = fc->cb_break;
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
@@ -2370,5 +2396,180 @@ int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
call->cb_break = fc->cb_break;
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &fids[0]);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
afs_make_call(&fc->ac, call, GFP_NOFS);
return afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
* deliver reply data to an FS.FetchACL
*/
static int afs_deliver_fs_fetch_acl(struct afs_call *call)
{
struct afs_vnode *vnode = call->reply[1];
struct afs_acl *acl;
const __be32 *bp;
unsigned int size;
int ret;
_enter("{%u}", call->unmarshall);
switch (call->unmarshall) {
case 0:
afs_extract_to_tmp(call);
call->unmarshall++;
/* extract the returned data length */
case 1:
ret = afs_extract_data(call, true);
if (ret < 0)
return ret;
size = call->count2 = ntohl(call->tmp);
size = round_up(size, 4);
acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
if (!acl)
return -ENOMEM;
call->reply[0] = acl;
acl->size = call->count2;
afs_extract_begin(call, acl->data, size);
call->unmarshall++;
/* extract the returned data */
case 2:
ret = afs_extract_data(call, true);
if (ret < 0)
return ret;
afs_extract_to_buf(call, (21 + 6) * 4);
call->unmarshall++;
/* extract the metadata */
case 3:
ret = afs_extract_data(call, false);
if (ret < 0)
return ret;
bp = call->buffer;
ret = afs_decode_status(call, &bp, &vnode->status, vnode,
&vnode->status.data_version, NULL);
if (ret < 0)
return ret;
xdr_decode_AFSVolSync(&bp, call->reply[2]);
call->unmarshall++;
case 4:
break;
}
_leave(" = 0 [done]");
return 0;
}
static void afs_destroy_fs_fetch_acl(struct afs_call *call)
{
kfree(call->reply[0]);
afs_flat_call_destructor(call);
}
/*
* FS.FetchACL operation type
*/
static const struct afs_call_type afs_RXFSFetchACL = {
.name = "FS.FetchACL",
.op = afs_FS_FetchACL,
.deliver = afs_deliver_fs_fetch_acl,
.destructor = afs_destroy_fs_fetch_acl,
};
/*
* Fetch the ACL for a file.
*/
struct afs_acl *afs_fs_fetch_acl(struct afs_fs_cursor *fc)
{
struct afs_vnode *vnode = fc->vnode;
struct afs_call *call;
struct afs_net *net = afs_v2net(vnode);
__be32 *bp;
_enter(",%x,{%llx:%llu},,",
key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
call = afs_alloc_flat_call(net, &afs_RXFSFetchACL, 16, (21 + 6) * 4);
if (!call) {
fc->ac.error = -ENOMEM;
return ERR_PTR(-ENOMEM);
}
call->key = fc->key;
call->reply[0] = NULL;
call->reply[1] = vnode;
call->reply[2] = NULL; /* volsync */
call->ret_reply0 = true;
/* marshall the parameters */
bp = call->request;
bp[0] = htonl(FSFETCHACL);
bp[1] = htonl(vnode->fid.vid);
bp[2] = htonl(vnode->fid.vnode);
bp[3] = htonl(vnode->fid.unique);
call->cb_break = fc->cb_break;
afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
afs_make_call(&fc->ac, call, GFP_KERNEL);
return (struct afs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
}
/*
* FS.StoreACL operation type
*/
static const struct afs_call_type afs_RXFSStoreACL = {
.name = "FS.StoreACL",
.op = afs_FS_StoreACL,
.deliver = afs_deliver_fs_status_and_vol,
.destructor = afs_flat_call_destructor,
};
/*
* Fetch the ACL for a file.
*/
int afs_fs_store_acl(struct afs_fs_cursor *fc, const struct afs_acl *acl)
{
struct afs_vnode *vnode = fc->vnode;
struct afs_call *call;
struct afs_net *net = afs_v2net(vnode);
size_t size;
__be32 *bp;
_enter(",%x,{%llx:%llu},,",
key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
size = round_up(acl->size, 4);
call = afs_alloc_flat_call(net, &afs_RXFSStoreACL,
5 * 4 + size, (21 + 6) * 4);
if (!call) {
fc->ac.error = -ENOMEM;
return -ENOMEM;
}
call->key = fc->key;
call->reply[0] = vnode;
call->reply[2] = NULL; /* volsync */
/* marshall the parameters */
bp = call->request;
bp[0] = htonl(FSSTOREACL);
bp[1] = htonl(vnode->fid.vid);
bp[2] = htonl(vnode->fid.vnode);
bp[3] = htonl(vnode->fid.unique);
bp[4] = htonl(acl->size);
memcpy(&bp[5], acl->data, acl->size);
if (acl->size != size)
memset((void *)&bp[5] + acl->size, 0, size - acl->size);
trace_afs_make_fs_call(call, &vnode->fid);
afs_make_call(&fc->ac, call, GFP_KERNEL);
return afs_wait_for_call_to_complete(call, &fc->ac);
}