Commit 5b7ad877 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'afs-fixes-20231124' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs

Pull AFS fixes from David Howells:

 - Fix the afs_server_list struct to be cleaned up with RCU

 - Fix afs to translate a no-data result from a DNS lookup into ENOENT,
   not EDESTADDRREQ for consistency with OpenAFS

 - Fix afs to translate a negative DNS lookup result into ENOENT rather
   than EDESTADDRREQ

 - Fix file locking on R/O volumes to operate in local mode as the
   server doesn't handle exclusive locks on such files

 - Set SB_RDONLY on superblocks for RO and Backup volumes so that the
   VFS can see that they're read only

* tag 'afs-fixes-20231124' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
  afs: Mark a superblock for an R/O or Backup volume as SB_RDONLY
  afs: Fix file locking on R/O volumes to operate in local mode
  afs: Return ENOENT if no cell DNS record can be found
  afs: Make error on cell lookup failure consistent with OpenAFS
  afs: Fix afs_server_list to be cleaned up with RCU
parents fa2b906f 68516f60
...@@ -132,8 +132,8 @@ static int afs_probe_cell_name(struct dentry *dentry) ...@@ -132,8 +132,8 @@ static int afs_probe_cell_name(struct dentry *dentry)
ret = dns_query(net->net, "afsdb", name, len, "srv=1", ret = dns_query(net->net, "afsdb", name, len, "srv=1",
NULL, NULL, false); NULL, NULL, false);
if (ret == -ENODATA) if (ret == -ENODATA || ret == -ENOKEY)
ret = -EDESTADDRREQ; ret = -ENOENT;
return ret; return ret;
} }
......
...@@ -553,6 +553,7 @@ struct afs_server_entry { ...@@ -553,6 +553,7 @@ struct afs_server_entry {
}; };
struct afs_server_list { struct afs_server_list {
struct rcu_head rcu;
afs_volid_t vids[AFS_MAXTYPES]; /* Volume IDs */ afs_volid_t vids[AFS_MAXTYPES]; /* Volume IDs */
refcount_t usage; refcount_t usage;
unsigned char nr_servers; unsigned char nr_servers;
......
...@@ -17,7 +17,7 @@ void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist) ...@@ -17,7 +17,7 @@ void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist)
for (i = 0; i < slist->nr_servers; i++) for (i = 0; i < slist->nr_servers; i++)
afs_unuse_server(net, slist->servers[i].server, afs_unuse_server(net, slist->servers[i].server,
afs_server_trace_put_slist); afs_server_trace_put_slist);
kfree(slist); kfree_rcu(slist, rcu);
} }
} }
......
...@@ -407,6 +407,10 @@ static int afs_validate_fc(struct fs_context *fc) ...@@ -407,6 +407,10 @@ static int afs_validate_fc(struct fs_context *fc)
return PTR_ERR(volume); return PTR_ERR(volume);
ctx->volume = volume; ctx->volume = volume;
if (volume->type != AFSVL_RWVOL) {
ctx->flock_mode = afs_flock_mode_local;
fc->sb_flags |= SB_RDONLY;
}
} }
return 0; return 0;
......
...@@ -58,6 +58,12 @@ static bool afs_start_vl_iteration(struct afs_vl_cursor *vc) ...@@ -58,6 +58,12 @@ static bool afs_start_vl_iteration(struct afs_vl_cursor *vc)
} }
/* Status load is ordered after lookup counter load */ /* Status load is ordered after lookup counter load */
if (cell->dns_status == DNS_LOOKUP_GOT_NOT_FOUND) {
pr_warn("No record of cell %s\n", cell->name);
vc->error = -ENOENT;
return false;
}
if (cell->dns_source == DNS_RECORD_UNAVAILABLE) { if (cell->dns_source == DNS_RECORD_UNAVAILABLE) {
vc->error = -EDESTADDRREQ; vc->error = -EDESTADDRREQ;
return false; return false;
...@@ -285,6 +291,7 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc) ...@@ -285,6 +291,7 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc)
*/ */
static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc) static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc)
{ {
struct afs_cell *cell = vc->cell;
static int count; static int count;
int i; int i;
...@@ -294,6 +301,9 @@ static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc) ...@@ -294,6 +301,9 @@ static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc)
rcu_read_lock(); rcu_read_lock();
pr_notice("EDESTADDR occurred\n"); pr_notice("EDESTADDR occurred\n");
pr_notice("CELL: %s err=%d\n", cell->name, cell->error);
pr_notice("DNS: src=%u st=%u lc=%x\n",
cell->dns_source, cell->dns_status, cell->dns_lookup_count);
pr_notice("VC: ut=%lx ix=%u ni=%hu fl=%hx err=%hd\n", pr_notice("VC: ut=%lx ix=%u ni=%hu fl=%hx err=%hd\n",
vc->untried, vc->index, vc->nr_iterations, vc->flags, vc->error); vc->untried, vc->index, vc->nr_iterations, vc->flags, vc->error);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment