summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-12 14:59:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-12 14:59:06 -0400
commit19e8a2f875a56009c0ce30389964aca452a85510 (patch)
tree22ad79d41c34555444030f34bebb979367d7ef32 /fs
parent5d1365940a68dd57b031b6e3c07d7d451cd69daf (diff)
parent5a8132761609bd7e42db642d6f157140d5bf2ae8 (diff)
Merge branch 'afs-dh' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull AFS updates from Al Viro: "The AFS series posted by dhowells depended upon lookup_one_len() rework; now that prereq is in the mainline, that series had been rebased on top of it and got some exposure and testing..." * 'afs-dh' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: afs: Do better accretion of small writes on newly created content afs: Add stats for data transfer operations afs: Trace protocol errors afs: Locally edit directory data for mkdir/create/unlink/... afs: Adjust the directory XDR structures afs: Split the directory content defs into a header afs: Fix directory handling afs: Split the dynroot stuff out and give it its own ops tables afs: Keep track of invalid-before version for dentry coherency afs: Rearrange status mapping afs: Make it possible to get the data version in readpage afs: Init inode before accessing cache afs: Introduce a statistics proc file afs: Dump bad status record afs: Implement @cell substitution handling afs: Implement @sys substitution handling afs: Prospectively look up extra files when doing a single lookup afs: Don't over-increment the cell usage count when pinning it afs: Fix checker warnings vfs: Remove the const from dir_context::actor
Diffstat (limited to 'fs')
-rw-r--r--fs/afs/Makefile2
-rw-r--r--fs/afs/addr_list.c6
-rw-r--r--fs/afs/afs.h27
-rw-r--r--fs/afs/afs_fs.h2
-rw-r--r--fs/afs/callback.c29
-rw-r--r--fs/afs/cell.c12
-rw-r--r--fs/afs/cmservice.c22
-rw-r--r--fs/afs/dir.c923
-rw-r--r--fs/afs/dir_edit.c505
-rw-r--r--fs/afs/dynroot.c209
-rw-r--r--fs/afs/file.c27
-rw-r--r--fs/afs/flock.c2
-rw-r--r--fs/afs/fsclient.c622
-rw-r--r--fs/afs/inode.c69
-rw-r--r--fs/afs/internal.h105
-rw-r--r--fs/afs/main.c44
-rw-r--r--fs/afs/proc.c326
-rw-r--r--fs/afs/rotate.c2
-rw-r--r--fs/afs/rxrpc.c9
-rw-r--r--fs/afs/security.c13
-rw-r--r--fs/afs/server.c14
-rw-r--r--fs/afs/super.c11
-rw-r--r--fs/afs/vlclient.c28
-rw-r--r--fs/afs/write.c41
-rw-r--r--fs/afs/xdr_fs.h103
25 files changed, 2562 insertions, 591 deletions
diff --git a/fs/afs/Makefile b/fs/afs/Makefile
index 45b7fc405fa6..532acae25453 100644
--- a/fs/afs/Makefile
+++ b/fs/afs/Makefile
@@ -12,6 +12,8 @@ kafs-objs := \
12 cell.o \ 12 cell.o \
13 cmservice.o \ 13 cmservice.o \
14 dir.o \ 14 dir.o \
15 dir_edit.o \
16 dynroot.o \
15 file.o \ 17 file.o \
16 flock.o \ 18 flock.o \
17 fsclient.o \ 19 fsclient.o \
diff --git a/fs/afs/addr_list.c b/fs/afs/addr_list.c
index fd9f28b8a933..3bedfed608a2 100644
--- a/fs/afs/addr_list.c
+++ b/fs/afs/addr_list.c
@@ -243,9 +243,9 @@ void afs_merge_fs_addr4(struct afs_addr_list *alist, __be32 xdr, u16 port)
243 xport == a->sin6_port) 243 xport == a->sin6_port)
244 return; 244 return;
245 if (xdr == a->sin6_addr.s6_addr32[3] && 245 if (xdr == a->sin6_addr.s6_addr32[3] &&
246 xport < a->sin6_port) 246 (u16 __force)xport < (u16 __force)a->sin6_port)
247 break; 247 break;
248 if (xdr < a->sin6_addr.s6_addr32[3]) 248 if ((u32 __force)xdr < (u32 __force)a->sin6_addr.s6_addr32[3])
249 break; 249 break;
250 } 250 }
251 251
@@ -280,7 +280,7 @@ void afs_merge_fs_addr6(struct afs_addr_list *alist, __be32 *xdr, u16 port)
280 xport == a->sin6_port) 280 xport == a->sin6_port)
281 return; 281 return;
282 if (diff == 0 && 282 if (diff == 0 &&
283 xport < a->sin6_port) 283 (u16 __force)xport < (u16 __force)a->sin6_port)
284 break; 284 break;
285 if (diff < 0) 285 if (diff < 0)
286 break; 286 break;
diff --git a/fs/afs/afs.h b/fs/afs/afs.h
index b94d0edc2b78..b4ff1f7ae4ab 100644
--- a/fs/afs/afs.h
+++ b/fs/afs/afs.h
@@ -67,10 +67,14 @@ typedef enum {
67} afs_callback_type_t; 67} afs_callback_type_t;
68 68
69struct afs_callback { 69struct afs_callback {
70 struct afs_fid fid; /* file identifier */ 70 unsigned version; /* Callback version */
71 unsigned version; /* callback version */ 71 unsigned expiry; /* Time at which expires */
72 unsigned expiry; /* time at which expires */ 72 afs_callback_type_t type; /* Type of callback */
73 afs_callback_type_t type; /* type of callback */ 73};
74
75struct afs_callback_break {
76 struct afs_fid fid; /* File identifier */
77 struct afs_callback cb; /* Callback details */
74}; 78};
75 79
76#define AFSCBMAX 50 /* maximum callbacks transferred per bulk op */ 80#define AFSCBMAX 50 /* maximum callbacks transferred per bulk op */
@@ -123,21 +127,20 @@ typedef u32 afs_access_t;
123 * AFS file status information 127 * AFS file status information
124 */ 128 */
125struct afs_file_status { 129struct afs_file_status {
126 unsigned if_version; /* interface version */ 130 u64 size; /* file size */
127#define AFS_FSTATUS_VERSION 1 131 afs_dataversion_t data_version; /* current data version */
132 time_t mtime_client; /* last time client changed data */
133 time_t mtime_server; /* last time server changed data */
134 unsigned abort_code; /* Abort if bulk-fetching this failed */
128 135
129 afs_file_type_t type; /* file type */ 136 afs_file_type_t type; /* file type */
130 unsigned nlink; /* link count */ 137 unsigned nlink; /* link count */
131 u64 size; /* file size */
132 afs_dataversion_t data_version; /* current data version */
133 u32 author; /* author ID */ 138 u32 author; /* author ID */
134 kuid_t owner; /* owner ID */ 139 u32 owner; /* owner ID */
135 kgid_t group; /* group ID */ 140 u32 group; /* group ID */
136 afs_access_t caller_access; /* access rights for authenticated caller */ 141 afs_access_t caller_access; /* access rights for authenticated caller */
137 afs_access_t anon_access; /* access rights for unauthenticated caller */ 142 afs_access_t anon_access; /* access rights for unauthenticated caller */
138 umode_t mode; /* UNIX mode */ 143 umode_t mode; /* UNIX mode */
139 time_t mtime_client; /* last time client changed data */
140 time_t mtime_server; /* last time server changed data */
141 s32 lock_count; /* file lock count (0=UNLK -1=WRLCK +ve=#RDLCK */ 144 s32 lock_count; /* file lock count (0=UNLK -1=WRLCK +ve=#RDLCK */
142}; 145};
143 146
diff --git a/fs/afs/afs_fs.h b/fs/afs/afs_fs.h
index d47b6d01e4c0..ddfa88a7a9c0 100644
--- a/fs/afs/afs_fs.h
+++ b/fs/afs/afs_fs.h
@@ -31,10 +31,12 @@ enum AFS_FS_Operations {
31 FSGETVOLUMEINFO = 148, /* AFS Get information about a volume */ 31 FSGETVOLUMEINFO = 148, /* AFS Get information about a volume */
32 FSGETVOLUMESTATUS = 149, /* AFS Get volume status information */ 32 FSGETVOLUMESTATUS = 149, /* AFS Get volume status information */
33 FSGETROOTVOLUME = 151, /* AFS Get root volume name */ 33 FSGETROOTVOLUME = 151, /* AFS Get root volume name */
34 FSBULKSTATUS = 155, /* AFS Fetch multiple file statuses */
34 FSSETLOCK = 156, /* AFS Request a file lock */ 35 FSSETLOCK = 156, /* AFS Request a file lock */
35 FSEXTENDLOCK = 157, /* AFS Extend a file lock */ 36 FSEXTENDLOCK = 157, /* AFS Extend a file lock */
36 FSRELEASELOCK = 158, /* AFS Release a file lock */ 37 FSRELEASELOCK = 158, /* AFS Release a file lock */
37 FSLOOKUP = 161, /* AFS lookup file in directory */ 38 FSLOOKUP = 161, /* AFS lookup file in directory */
39 FSINLINEBULKSTATUS = 65536, /* AFS Fetch multiple file statuses with inline errors */
38 FSFETCHDATA64 = 65537, /* AFS Fetch file data */ 40 FSFETCHDATA64 = 65537, /* AFS Fetch file data */
39 FSSTOREDATA64 = 65538, /* AFS Store file data */ 41 FSSTOREDATA64 = 65538, /* AFS Store file data */
40 FSGIVEUPALLCALLBACKS = 65539, /* AFS Give up all outstanding callbacks on a server */ 42 FSGIVEUPALLCALLBACKS = 65539, /* AFS Give up all outstanding callbacks on a server */
diff --git a/fs/afs/callback.c b/fs/afs/callback.c
index f4291b576054..abd9a84f4e88 100644
--- a/fs/afs/callback.c
+++ b/fs/afs/callback.c
@@ -97,26 +97,6 @@ again:
97} 97}
98 98
99/* 99/*
100 * Set a vnode's interest on a server.
101 */
102void afs_set_cb_interest(struct afs_vnode *vnode, struct afs_cb_interest *cbi)
103{
104 struct afs_cb_interest *old_cbi = NULL;
105
106 if (vnode->cb_interest == cbi)
107 return;
108
109 write_seqlock(&vnode->cb_lock);
110 if (vnode->cb_interest != cbi) {
111 afs_get_cb_interest(cbi);
112 old_cbi = vnode->cb_interest;
113 vnode->cb_interest = cbi;
114 }
115 write_sequnlock(&vnode->cb_lock);
116 afs_put_cb_interest(afs_v2net(vnode), cbi);
117}
118
119/*
120 * Remove an interest on a server. 100 * Remove an interest on a server.
121 */ 101 */
122void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi) 102void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi)
@@ -150,6 +130,7 @@ void afs_break_callback(struct afs_vnode *vnode)
150 130
151 write_seqlock(&vnode->cb_lock); 131 write_seqlock(&vnode->cb_lock);
152 132
133 clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
153 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { 134 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
154 vnode->cb_break++; 135 vnode->cb_break++;
155 afs_clear_permits(vnode); 136 afs_clear_permits(vnode);
@@ -207,7 +188,7 @@ static void afs_break_one_callback(struct afs_server *server,
207 * allow the fileserver to break callback promises 188 * allow the fileserver to break callback promises
208 */ 189 */
209void afs_break_callbacks(struct afs_server *server, size_t count, 190void afs_break_callbacks(struct afs_server *server, size_t count,
210 struct afs_callback callbacks[]) 191 struct afs_callback_break *callbacks)
211{ 192{
212 _enter("%p,%zu,", server, count); 193 _enter("%p,%zu,", server, count);
213 194
@@ -219,9 +200,9 @@ void afs_break_callbacks(struct afs_server *server, size_t count,
219 callbacks->fid.vid, 200 callbacks->fid.vid,
220 callbacks->fid.vnode, 201 callbacks->fid.vnode,
221 callbacks->fid.unique, 202 callbacks->fid.unique,
222 callbacks->version, 203 callbacks->cb.version,
223 callbacks->expiry, 204 callbacks->cb.expiry,
224 callbacks->type 205 callbacks->cb.type
225 ); 206 );
226 afs_break_one_callback(server, &callbacks->fid); 207 afs_break_one_callback(server, &callbacks->fid);
227 } 208 }
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 4235a05afc76..fdf4c36cff79 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -18,7 +18,7 @@
18#include <keys/rxrpc-type.h> 18#include <keys/rxrpc-type.h>
19#include "internal.h" 19#include "internal.h"
20 20
21unsigned __read_mostly afs_cell_gc_delay = 10; 21static unsigned __read_mostly afs_cell_gc_delay = 10;
22 22
23static void afs_manage_cell(struct work_struct *); 23static void afs_manage_cell(struct work_struct *);
24 24
@@ -75,7 +75,7 @@ struct afs_cell *afs_lookup_cell_rcu(struct afs_net *net,
75 cell = rcu_dereference_raw(net->ws_cell); 75 cell = rcu_dereference_raw(net->ws_cell);
76 if (cell) { 76 if (cell) {
77 afs_get_cell(cell); 77 afs_get_cell(cell);
78 continue; 78 break;
79 } 79 }
80 ret = -EDESTADDRREQ; 80 ret = -EDESTADDRREQ;
81 continue; 81 continue;
@@ -130,6 +130,8 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,
130 _leave(" = -ENAMETOOLONG"); 130 _leave(" = -ENAMETOOLONG");
131 return ERR_PTR(-ENAMETOOLONG); 131 return ERR_PTR(-ENAMETOOLONG);
132 } 132 }
133 if (namelen == 5 && memcmp(name, "@cell", 5) == 0)
134 return ERR_PTR(-EINVAL);
133 135
134 _enter("%*.*s,%s", namelen, namelen, name, vllist); 136 _enter("%*.*s,%s", namelen, namelen, name, vllist);
135 137
@@ -334,8 +336,8 @@ int afs_cell_init(struct afs_net *net, const char *rootcell)
334 return PTR_ERR(new_root); 336 return PTR_ERR(new_root);
335 } 337 }
336 338
337 set_bit(AFS_CELL_FL_NO_GC, &new_root->flags); 339 if (!test_and_set_bit(AFS_CELL_FL_NO_GC, &new_root->flags))
338 afs_get_cell(new_root); 340 afs_get_cell(new_root);
339 341
340 /* install the new cell */ 342 /* install the new cell */
341 write_seqlock(&net->cells_lock); 343 write_seqlock(&net->cells_lock);
@@ -411,7 +413,7 @@ static void afs_cell_destroy(struct rcu_head *rcu)
411 413
412 ASSERTCMP(atomic_read(&cell->usage), ==, 0); 414 ASSERTCMP(atomic_read(&cell->usage), ==, 0);
413 415
414 afs_put_addrlist(cell->vl_addrs); 416 afs_put_addrlist(rcu_access_pointer(cell->vl_addrs));
415 key_put(cell->anonymous_key); 417 key_put(cell->anonymous_key);
416 kfree(cell); 418 kfree(cell);
417 419
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 41e277f57b20..357de908df3a 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -178,8 +178,8 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
178 */ 178 */
179static int afs_deliver_cb_callback(struct afs_call *call) 179static int afs_deliver_cb_callback(struct afs_call *call)
180{ 180{
181 struct afs_callback_break *cb;
181 struct sockaddr_rxrpc srx; 182 struct sockaddr_rxrpc srx;
182 struct afs_callback *cb;
183 struct afs_server *server; 183 struct afs_server *server;
184 __be32 *bp; 184 __be32 *bp;
185 int ret, loop; 185 int ret, loop;
@@ -201,7 +201,7 @@ static int afs_deliver_cb_callback(struct afs_call *call)
201 call->count = ntohl(call->tmp); 201 call->count = ntohl(call->tmp);
202 _debug("FID count: %u", call->count); 202 _debug("FID count: %u", call->count);
203 if (call->count > AFSCBMAX) 203 if (call->count > AFSCBMAX)
204 return -EBADMSG; 204 return afs_protocol_error(call, -EBADMSG);
205 205
206 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL); 206 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
207 if (!call->buffer) 207 if (!call->buffer)
@@ -218,7 +218,7 @@ static int afs_deliver_cb_callback(struct afs_call *call)
218 218
219 _debug("unmarshall FID array"); 219 _debug("unmarshall FID array");
220 call->request = kcalloc(call->count, 220 call->request = kcalloc(call->count,
221 sizeof(struct afs_callback), 221 sizeof(struct afs_callback_break),
222 GFP_KERNEL); 222 GFP_KERNEL);
223 if (!call->request) 223 if (!call->request)
224 return -ENOMEM; 224 return -ENOMEM;
@@ -229,7 +229,7 @@ static int afs_deliver_cb_callback(struct afs_call *call)
229 cb->fid.vid = ntohl(*bp++); 229 cb->fid.vid = ntohl(*bp++);
230 cb->fid.vnode = ntohl(*bp++); 230 cb->fid.vnode = ntohl(*bp++);
231 cb->fid.unique = ntohl(*bp++); 231 cb->fid.unique = ntohl(*bp++);
232 cb->type = AFSCM_CB_UNTYPED; 232 cb->cb.type = AFSCM_CB_UNTYPED;
233 } 233 }
234 234
235 call->offset = 0; 235 call->offset = 0;
@@ -245,7 +245,7 @@ static int afs_deliver_cb_callback(struct afs_call *call)
245 call->count2 = ntohl(call->tmp); 245 call->count2 = ntohl(call->tmp);
246 _debug("CB count: %u", call->count2); 246 _debug("CB count: %u", call->count2);
247 if (call->count2 != call->count && call->count2 != 0) 247 if (call->count2 != call->count && call->count2 != 0)
248 return -EBADMSG; 248 return afs_protocol_error(call, -EBADMSG);
249 call->offset = 0; 249 call->offset = 0;
250 call->unmarshall++; 250 call->unmarshall++;
251 251
@@ -260,9 +260,9 @@ static int afs_deliver_cb_callback(struct afs_call *call)
260 cb = call->request; 260 cb = call->request;
261 bp = call->buffer; 261 bp = call->buffer;
262 for (loop = call->count2; loop > 0; loop--, cb++) { 262 for (loop = call->count2; loop > 0; loop--, cb++) {
263 cb->version = ntohl(*bp++); 263 cb->cb.version = ntohl(*bp++);
264 cb->expiry = ntohl(*bp++); 264 cb->cb.expiry = ntohl(*bp++);
265 cb->type = ntohl(*bp++); 265 cb->cb.type = ntohl(*bp++);
266 } 266 }
267 267
268 call->offset = 0; 268 call->offset = 0;
@@ -500,9 +500,9 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call)
500 500
501 b = call->buffer; 501 b = call->buffer;
502 r = call->request; 502 r = call->request;
503 r->time_low = ntohl(b[0]); 503 r->time_low = b[0];
504 r->time_mid = ntohl(b[1]); 504 r->time_mid = htons(ntohl(b[1]));
505 r->time_hi_and_version = ntohl(b[2]); 505 r->time_hi_and_version = htons(ntohl(b[2]));
506 r->clock_seq_hi_and_reserved = ntohl(b[3]); 506 r->clock_seq_hi_and_reserved = ntohl(b[3]);
507 r->clock_seq_low = ntohl(b[4]); 507 r->clock_seq_low = ntohl(b[4]);
508 508
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index ba2b458b36d1..5889f70d4d27 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -1,6 +1,6 @@
1/* dir.c: AFS filesystem directory handling 1/* dir.c: AFS filesystem directory handling
2 * 2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2002, 2018 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -10,27 +10,26 @@
10 */ 10 */
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/fs.h> 13#include <linux/fs.h>
16#include <linux/namei.h> 14#include <linux/namei.h>
17#include <linux/pagemap.h> 15#include <linux/pagemap.h>
16#include <linux/swap.h>
18#include <linux/ctype.h> 17#include <linux/ctype.h>
19#include <linux/sched.h> 18#include <linux/sched.h>
20#include <linux/dns_resolver.h> 19#include <linux/task_io_accounting_ops.h>
21#include "internal.h" 20#include "internal.h"
21#include "xdr_fs.h"
22 22
23static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, 23static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
24 unsigned int flags); 24 unsigned int flags);
25static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry,
26 unsigned int flags);
27static int afs_dir_open(struct inode *inode, struct file *file); 25static int afs_dir_open(struct inode *inode, struct file *file);
28static int afs_readdir(struct file *file, struct dir_context *ctx); 26static int afs_readdir(struct file *file, struct dir_context *ctx);
29static int afs_d_revalidate(struct dentry *dentry, unsigned int flags); 27static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
30static int afs_d_delete(const struct dentry *dentry); 28static int afs_d_delete(const struct dentry *dentry);
31static void afs_d_release(struct dentry *dentry); 29static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
32static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
33 loff_t fpos, u64 ino, unsigned dtype); 30 loff_t fpos, u64 ino, unsigned dtype);
31static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
32 loff_t fpos, u64 ino, unsigned dtype);
34static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, 33static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
35 bool excl); 34 bool excl);
36static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); 35static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
@@ -43,6 +42,14 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
43static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, 42static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
44 struct inode *new_dir, struct dentry *new_dentry, 43 struct inode *new_dir, struct dentry *new_dentry,
45 unsigned int flags); 44 unsigned int flags);
45static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags);
46static void afs_dir_invalidatepage(struct page *page, unsigned int offset,
47 unsigned int length);
48
49static int afs_dir_set_page_dirty(struct page *page)
50{
51 BUG(); /* This should never happen. */
52}
46 53
47const struct file_operations afs_dir_file_operations = { 54const struct file_operations afs_dir_file_operations = {
48 .open = afs_dir_open, 55 .open = afs_dir_open,
@@ -67,15 +74,10 @@ const struct inode_operations afs_dir_inode_operations = {
67 .listxattr = afs_listxattr, 74 .listxattr = afs_listxattr,
68}; 75};
69 76
70const struct file_operations afs_dynroot_file_operations = { 77const struct address_space_operations afs_dir_aops = {
71 .open = dcache_dir_open, 78 .set_page_dirty = afs_dir_set_page_dirty,
72 .release = dcache_dir_close, 79 .releasepage = afs_dir_releasepage,
73 .iterate_shared = dcache_readdir, 80 .invalidatepage = afs_dir_invalidatepage,
74 .llseek = dcache_dir_lseek,
75};
76
77const struct inode_operations afs_dynroot_inode_operations = {
78 .lookup = afs_dynroot_lookup,
79}; 81};
80 82
81const struct dentry_operations afs_fs_dentry_operations = { 83const struct dentry_operations afs_fs_dentry_operations = {
@@ -85,91 +87,38 @@ const struct dentry_operations afs_fs_dentry_operations = {
85 .d_automount = afs_d_automount, 87 .d_automount = afs_d_automount,
86}; 88};
87 89
88#define AFS_DIR_HASHTBL_SIZE 128 90struct afs_lookup_one_cookie {
89#define AFS_DIR_DIRENT_SIZE 32 91 struct dir_context ctx;
90#define AFS_DIRENT_PER_BLOCK 64 92 struct qstr name;
91 93 bool found;
92union afs_dirent { 94 struct afs_fid fid;
93 struct {
94 uint8_t valid;
95 uint8_t unused[1];
96 __be16 hash_next;
97 __be32 vnode;
98 __be32 unique;
99 uint8_t name[16];
100 uint8_t overflow[4]; /* if any char of the name (inc
101 * NUL) reaches here, consume
102 * the next dirent too */
103 } u;
104 uint8_t extended_name[32];
105};
106
107/* AFS directory page header (one at the beginning of every 2048-byte chunk) */
108struct afs_dir_pagehdr {
109 __be16 npages;
110 __be16 magic;
111#define AFS_DIR_MAGIC htons(1234)
112 uint8_t nentries;
113 uint8_t bitmap[8];
114 uint8_t pad[19];
115};
116
117/* directory block layout */
118union afs_dir_block {
119
120 struct afs_dir_pagehdr pagehdr;
121
122 struct {
123 struct afs_dir_pagehdr pagehdr;
124 uint8_t alloc_ctrs[128];
125 /* dir hash table */
126 uint16_t hashtable[AFS_DIR_HASHTBL_SIZE];
127 } hdr;
128
129 union afs_dirent dirents[AFS_DIRENT_PER_BLOCK];
130};
131
132/* layout on a linux VM page */
133struct afs_dir_page {
134 union afs_dir_block blocks[PAGE_SIZE / sizeof(union afs_dir_block)];
135}; 95};
136 96
137struct afs_lookup_cookie { 97struct afs_lookup_cookie {
138 struct dir_context ctx; 98 struct dir_context ctx;
139 struct afs_fid fid; 99 struct qstr name;
140 struct qstr name; 100 bool found;
141 int found; 101 bool one_only;
102 unsigned short nr_fids;
103 struct afs_file_status *statuses;
104 struct afs_callback *callbacks;
105 struct afs_fid fids[50];
142}; 106};
143 107
144/* 108/*
145 * check that a directory page is valid 109 * check that a directory page is valid
146 */ 110 */
147bool afs_dir_check_page(struct inode *dir, struct page *page) 111static bool afs_dir_check_page(struct afs_vnode *dvnode, struct page *page,
112 loff_t i_size)
148{ 113{
149 struct afs_dir_page *dbuf; 114 struct afs_xdr_dir_page *dbuf;
150 struct afs_vnode *vnode = AFS_FS_I(dir); 115 loff_t latter, off;
151 loff_t latter, i_size, off;
152 int tmp, qty; 116 int tmp, qty;
153 117
154#if 0
155 /* check the page count */
156 qty = desc.size / sizeof(dbuf->blocks[0]);
157 if (qty == 0)
158 goto error;
159
160 if (page->index == 0 && qty != ntohs(dbuf->blocks[0].pagehdr.npages)) {
161 printk("kAFS: %s(%lu): wrong number of dir blocks %d!=%hu\n",
162 __func__, dir->i_ino, qty,
163 ntohs(dbuf->blocks[0].pagehdr.npages));
164 goto error;
165 }
166#endif
167
168 /* Determine how many magic numbers there should be in this page, but 118 /* Determine how many magic numbers there should be in this page, but
169 * we must take care because the directory may change size under us. 119 * we must take care because the directory may change size under us.
170 */ 120 */
171 off = page_offset(page); 121 off = page_offset(page);
172 i_size = i_size_read(dir);
173 if (i_size <= off) 122 if (i_size <= off)
174 goto checked; 123 goto checked;
175 124
@@ -178,112 +127,225 @@ bool afs_dir_check_page(struct inode *dir, struct page *page)
178 qty = PAGE_SIZE; 127 qty = PAGE_SIZE;
179 else 128 else
180 qty = latter; 129 qty = latter;
181 qty /= sizeof(union afs_dir_block); 130 qty /= sizeof(union afs_xdr_dir_block);
182 131
183 /* check them */ 132 /* check them */
184 dbuf = page_address(page); 133 dbuf = kmap(page);
185 for (tmp = 0; tmp < qty; tmp++) { 134 for (tmp = 0; tmp < qty; tmp++) {
186 if (dbuf->blocks[tmp].pagehdr.magic != AFS_DIR_MAGIC) { 135 if (dbuf->blocks[tmp].hdr.magic != AFS_DIR_MAGIC) {
187 printk("kAFS: %s(%lx): bad magic %d/%d is %04hx\n", 136 printk("kAFS: %s(%lx): bad magic %d/%d is %04hx\n",
188 __func__, dir->i_ino, tmp, qty, 137 __func__, dvnode->vfs_inode.i_ino, tmp, qty,
189 ntohs(dbuf->blocks[tmp].pagehdr.magic)); 138 ntohs(dbuf->blocks[tmp].hdr.magic));
190 trace_afs_dir_check_failed(vnode, off, i_size); 139 trace_afs_dir_check_failed(dvnode, off, i_size);
140 kunmap(page);
191 goto error; 141 goto error;
192 } 142 }
143
144 /* Make sure each block is NUL terminated so we can reasonably
145 * use string functions on it. The filenames in the page
146 * *should* be NUL-terminated anyway.
147 */
148 ((u8 *)&dbuf->blocks[tmp])[AFS_DIR_BLOCK_SIZE - 1] = 0;
193 } 149 }
194 150
151 kunmap(page);
152
195checked: 153checked:
196 SetPageChecked(page); 154 afs_stat_v(dvnode, n_read_dir);
197 return true; 155 return true;
198 156
199error: 157error:
200 SetPageError(page);
201 return false; 158 return false;
202} 159}
203 160
204/* 161/*
205 * discard a page cached in the pagecache 162 * open an AFS directory file
206 */ 163 */
207static inline void afs_dir_put_page(struct page *page) 164static int afs_dir_open(struct inode *inode, struct file *file)
208{ 165{
209 kunmap(page); 166 _enter("{%lu}", inode->i_ino);
210 unlock_page(page); 167
211 put_page(page); 168 BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);
169 BUILD_BUG_ON(sizeof(union afs_xdr_dirent) != 32);
170
171 if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags))
172 return -ENOENT;
173
174 return afs_open(inode, file);
212} 175}
213 176
214/* 177/*
215 * get a page into the pagecache 178 * Read the directory into the pagecache in one go, scrubbing the previous
179 * contents. The list of pages is returned, pinning them so that they don't
180 * get reclaimed during the iteration.
216 */ 181 */
217static struct page *afs_dir_get_page(struct inode *dir, unsigned long index, 182static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
218 struct key *key)
219{ 183{
220 struct page *page; 184 struct afs_read *req;
221 _enter("{%lu},%lu", dir->i_ino, index); 185 loff_t i_size;
222 186 int nr_pages, nr_inline, i, n;
223 page = read_cache_page(dir->i_mapping, index, afs_page_filler, key); 187 int ret = -ENOMEM;
224 if (!IS_ERR(page)) { 188
225 lock_page(page); 189retry:
226 kmap(page); 190 i_size = i_size_read(&dvnode->vfs_inode);
227 if (unlikely(!PageChecked(page))) { 191 if (i_size < 2048)
228 if (PageError(page)) 192 return ERR_PTR(-EIO);
229 goto fail; 193 if (i_size > 2048 * 1024)
230 } 194 return ERR_PTR(-EFBIG);
195
196 _enter("%llu", i_size);
197
198 /* Get a request record to hold the page list. We want to hold it
199 * inline if we can, but we don't want to make an order 1 allocation.
200 */
201 nr_pages = (i_size + PAGE_SIZE - 1) / PAGE_SIZE;
202 nr_inline = nr_pages;
203 if (nr_inline > (PAGE_SIZE - sizeof(*req)) / sizeof(struct page *))
204 nr_inline = 0;
205
206 req = kzalloc(sizeof(*req) + sizeof(struct page *) * nr_inline,
207 GFP_KERNEL);
208 if (!req)
209 return ERR_PTR(-ENOMEM);
210
211 refcount_set(&req->usage, 1);
212 req->nr_pages = nr_pages;
213 req->actual_len = i_size; /* May change */
214 req->len = nr_pages * PAGE_SIZE; /* We can ask for more than there is */
215 req->data_version = dvnode->status.data_version; /* May change */
216 if (nr_inline > 0) {
217 req->pages = req->array;
218 } else {
219 req->pages = kcalloc(nr_pages, sizeof(struct page *),
220 GFP_KERNEL);
221 if (!req->pages)
222 goto error;
231 } 223 }
232 return page;
233 224
234fail: 225 /* Get a list of all the pages that hold or will hold the directory
235 afs_dir_put_page(page); 226 * content. We need to fill in any gaps that we might find where the
236 _leave(" = -EIO"); 227 * memory reclaimer has been at work. If there are any gaps, we will
237 return ERR_PTR(-EIO); 228 * need to reread the entire directory contents.
238} 229 */
230 i = 0;
231 do {
232 n = find_get_pages_contig(dvnode->vfs_inode.i_mapping, i,
233 req->nr_pages - i,
234 req->pages + i);
235 _debug("find %u at %u/%u", n, i, req->nr_pages);
236 if (n == 0) {
237 gfp_t gfp = dvnode->vfs_inode.i_mapping->gfp_mask;
238
239 if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
240 afs_stat_v(dvnode, n_inval);
241
242 ret = -ENOMEM;
243 req->pages[i] = __page_cache_alloc(gfp);
244 if (!req->pages[i])
245 goto error;
246 ret = add_to_page_cache_lru(req->pages[i],
247 dvnode->vfs_inode.i_mapping,
248 i, gfp);
249 if (ret < 0)
250 goto error;
251
252 set_page_private(req->pages[i], 1);
253 SetPagePrivate(req->pages[i]);
254 unlock_page(req->pages[i]);
255 i++;
256 } else {
257 i += n;
258 }
259 } while (i < req->nr_pages);
239 260
240/* 261 /* If we're going to reload, we need to lock all the pages to prevent
241 * open an AFS directory file 262 * races.
242 */ 263 */
243static int afs_dir_open(struct inode *inode, struct file *file) 264 if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) {
244{ 265 ret = -ERESTARTSYS;
245 _enter("{%lu}", inode->i_ino); 266 for (i = 0; i < req->nr_pages; i++)
267 if (lock_page_killable(req->pages[i]) < 0)
268 goto error_unlock;
246 269
247 BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048); 270 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
248 BUILD_BUG_ON(sizeof(union afs_dirent) != 32); 271 goto success;
249 272
250 if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags)) 273 ret = afs_fetch_data(dvnode, key, req);
251 return -ENOENT; 274 if (ret < 0)
275 goto error_unlock_all;
252 276
253 return afs_open(inode, file); 277 task_io_account_read(PAGE_SIZE * req->nr_pages);
278
279 if (req->len < req->file_size)
280 goto content_has_grown;
281
282 /* Validate the data we just read. */
283 ret = -EIO;
284 for (i = 0; i < req->nr_pages; i++)
285 if (!afs_dir_check_page(dvnode, req->pages[i],
286 req->actual_len))
287 goto error_unlock_all;
288
289 // TODO: Trim excess pages
290
291 set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags);
292 }
293
294success:
295 i = req->nr_pages;
296 while (i > 0)
297 unlock_page(req->pages[--i]);
298 return req;
299
300error_unlock_all:
301 i = req->nr_pages;
302error_unlock:
303 while (i > 0)
304 unlock_page(req->pages[--i]);
305error:
306 afs_put_read(req);
307 _leave(" = %d", ret);
308 return ERR_PTR(ret);
309
310content_has_grown:
311 i = req->nr_pages;
312 while (i > 0)
313 unlock_page(req->pages[--i]);
314 afs_put_read(req);
315 goto retry;
254} 316}
255 317
256/* 318/*
257 * deal with one block in an AFS directory 319 * deal with one block in an AFS directory
258 */ 320 */
259static int afs_dir_iterate_block(struct dir_context *ctx, 321static int afs_dir_iterate_block(struct dir_context *ctx,
260 union afs_dir_block *block, 322 union afs_xdr_dir_block *block,
261 unsigned blkoff) 323 unsigned blkoff)
262{ 324{
263 union afs_dirent *dire; 325 union afs_xdr_dirent *dire;
264 unsigned offset, next, curr; 326 unsigned offset, next, curr;
265 size_t nlen; 327 size_t nlen;
266 int tmp; 328 int tmp;
267 329
268 _enter("%u,%x,%p,,",(unsigned)ctx->pos,blkoff,block); 330 _enter("%u,%x,%p,,",(unsigned)ctx->pos,blkoff,block);
269 331
270 curr = (ctx->pos - blkoff) / sizeof(union afs_dirent); 332 curr = (ctx->pos - blkoff) / sizeof(union afs_xdr_dirent);
271 333
272 /* walk through the block, an entry at a time */ 334 /* walk through the block, an entry at a time */
273 for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries; 335 for (offset = (blkoff == 0 ? AFS_DIR_RESV_BLOCKS0 : AFS_DIR_RESV_BLOCKS);
274 offset < AFS_DIRENT_PER_BLOCK; 336 offset < AFS_DIR_SLOTS_PER_BLOCK;
275 offset = next 337 offset = next
276 ) { 338 ) {
277 next = offset + 1; 339 next = offset + 1;
278 340
279 /* skip entries marked unused in the bitmap */ 341 /* skip entries marked unused in the bitmap */
280 if (!(block->pagehdr.bitmap[offset / 8] & 342 if (!(block->hdr.bitmap[offset / 8] &
281 (1 << (offset % 8)))) { 343 (1 << (offset % 8)))) {
282 _debug("ENT[%zu.%u]: unused", 344 _debug("ENT[%zu.%u]: unused",
283 blkoff / sizeof(union afs_dir_block), offset); 345 blkoff / sizeof(union afs_xdr_dir_block), offset);
284 if (offset >= curr) 346 if (offset >= curr)
285 ctx->pos = blkoff + 347 ctx->pos = blkoff +
286 next * sizeof(union afs_dirent); 348 next * sizeof(union afs_xdr_dirent);
287 continue; 349 continue;
288 } 350 }
289 351
@@ -291,34 +353,34 @@ static int afs_dir_iterate_block(struct dir_context *ctx,
291 dire = &block->dirents[offset]; 353 dire = &block->dirents[offset];
292 nlen = strnlen(dire->u.name, 354 nlen = strnlen(dire->u.name,
293 sizeof(*block) - 355 sizeof(*block) -
294 offset * sizeof(union afs_dirent)); 356 offset * sizeof(union afs_xdr_dirent));
295 357
296 _debug("ENT[%zu.%u]: %s %zu \"%s\"", 358 _debug("ENT[%zu.%u]: %s %zu \"%s\"",
297 blkoff / sizeof(union afs_dir_block), offset, 359 blkoff / sizeof(union afs_xdr_dir_block), offset,
298 (offset < curr ? "skip" : "fill"), 360 (offset < curr ? "skip" : "fill"),
299 nlen, dire->u.name); 361 nlen, dire->u.name);
300 362
301 /* work out where the next possible entry is */ 363 /* work out where the next possible entry is */
302 for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_dirent)) { 364 for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_xdr_dirent)) {
303 if (next >= AFS_DIRENT_PER_BLOCK) { 365 if (next >= AFS_DIR_SLOTS_PER_BLOCK) {
304 _debug("ENT[%zu.%u]:" 366 _debug("ENT[%zu.%u]:"
305 " %u travelled beyond end dir block" 367 " %u travelled beyond end dir block"
306 " (len %u/%zu)", 368 " (len %u/%zu)",
307 blkoff / sizeof(union afs_dir_block), 369 blkoff / sizeof(union afs_xdr_dir_block),
308 offset, next, tmp, nlen); 370 offset, next, tmp, nlen);
309 return -EIO; 371 return -EIO;
310 } 372 }
311 if (!(block->pagehdr.bitmap[next / 8] & 373 if (!(block->hdr.bitmap[next / 8] &
312 (1 << (next % 8)))) { 374 (1 << (next % 8)))) {
313 _debug("ENT[%zu.%u]:" 375 _debug("ENT[%zu.%u]:"
314 " %u unmarked extension (len %u/%zu)", 376 " %u unmarked extension (len %u/%zu)",
315 blkoff / sizeof(union afs_dir_block), 377 blkoff / sizeof(union afs_xdr_dir_block),
316 offset, next, tmp, nlen); 378 offset, next, tmp, nlen);
317 return -EIO; 379 return -EIO;
318 } 380 }
319 381
320 _debug("ENT[%zu.%u]: ext %u/%zu", 382 _debug("ENT[%zu.%u]: ext %u/%zu",
321 blkoff / sizeof(union afs_dir_block), 383 blkoff / sizeof(union afs_xdr_dir_block),
322 next, tmp, nlen); 384 next, tmp, nlen);
323 next++; 385 next++;
324 } 386 }
@@ -330,13 +392,14 @@ static int afs_dir_iterate_block(struct dir_context *ctx,
330 /* found the next entry */ 392 /* found the next entry */
331 if (!dir_emit(ctx, dire->u.name, nlen, 393 if (!dir_emit(ctx, dire->u.name, nlen,
332 ntohl(dire->u.vnode), 394 ntohl(dire->u.vnode),
333 ctx->actor == afs_lookup_filldir ? 395 (ctx->actor == afs_lookup_filldir ||
396 ctx->actor == afs_lookup_one_filldir)?
334 ntohl(dire->u.unique) : DT_UNKNOWN)) { 397 ntohl(dire->u.unique) : DT_UNKNOWN)) {
335 _leave(" = 0 [full]"); 398 _leave(" = 0 [full]");
336 return 0; 399 return 0;
337 } 400 }
338 401
339 ctx->pos = blkoff + next * sizeof(union afs_dirent); 402 ctx->pos = blkoff + next * sizeof(union afs_xdr_dirent);
340 } 403 }
341 404
342 _leave(" = 1 [more]"); 405 _leave(" = 1 [more]");
@@ -349,8 +412,10 @@ static int afs_dir_iterate_block(struct dir_context *ctx,
349static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, 412static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
350 struct key *key) 413 struct key *key)
351{ 414{
352 union afs_dir_block *dblock; 415 struct afs_vnode *dvnode = AFS_FS_I(dir);
353 struct afs_dir_page *dbuf; 416 struct afs_xdr_dir_page *dbuf;
417 union afs_xdr_dir_block *dblock;
418 struct afs_read *req;
354 struct page *page; 419 struct page *page;
355 unsigned blkoff, limit; 420 unsigned blkoff, limit;
356 int ret; 421 int ret;
@@ -362,45 +427,53 @@ static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
362 return -ESTALE; 427 return -ESTALE;
363 } 428 }
364 429
430 req = afs_read_dir(dvnode, key);
431 if (IS_ERR(req))
432 return PTR_ERR(req);
433
365 /* round the file position up to the next entry boundary */ 434 /* round the file position up to the next entry boundary */
366 ctx->pos += sizeof(union afs_dirent) - 1; 435 ctx->pos += sizeof(union afs_xdr_dirent) - 1;
367 ctx->pos &= ~(sizeof(union afs_dirent) - 1); 436 ctx->pos &= ~(sizeof(union afs_xdr_dirent) - 1);
368 437
369 /* walk through the blocks in sequence */ 438 /* walk through the blocks in sequence */
370 ret = 0; 439 ret = 0;
371 while (ctx->pos < dir->i_size) { 440 while (ctx->pos < req->actual_len) {
372 blkoff = ctx->pos & ~(sizeof(union afs_dir_block) - 1); 441 blkoff = ctx->pos & ~(sizeof(union afs_xdr_dir_block) - 1);
373 442
374 /* fetch the appropriate page from the directory */ 443 /* Fetch the appropriate page from the directory and re-add it
375 page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key); 444 * to the LRU.
376 if (IS_ERR(page)) { 445 */
377 ret = PTR_ERR(page); 446 page = req->pages[blkoff / PAGE_SIZE];
447 if (!page) {
448 ret = -EIO;
378 break; 449 break;
379 } 450 }
451 mark_page_accessed(page);
380 452
381 limit = blkoff & ~(PAGE_SIZE - 1); 453 limit = blkoff & ~(PAGE_SIZE - 1);
382 454
383 dbuf = page_address(page); 455 dbuf = kmap(page);
384 456
385 /* deal with the individual blocks stashed on this page */ 457 /* deal with the individual blocks stashed on this page */
386 do { 458 do {
387 dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) / 459 dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) /
388 sizeof(union afs_dir_block)]; 460 sizeof(union afs_xdr_dir_block)];
389 ret = afs_dir_iterate_block(ctx, dblock, blkoff); 461 ret = afs_dir_iterate_block(ctx, dblock, blkoff);
390 if (ret != 1) { 462 if (ret != 1) {
391 afs_dir_put_page(page); 463 kunmap(page);
392 goto out; 464 goto out;
393 } 465 }
394 466
395 blkoff += sizeof(union afs_dir_block); 467 blkoff += sizeof(union afs_xdr_dir_block);
396 468
397 } while (ctx->pos < dir->i_size && blkoff < limit); 469 } while (ctx->pos < dir->i_size && blkoff < limit);
398 470
399 afs_dir_put_page(page); 471 kunmap(page);
400 ret = 0; 472 ret = 0;
401 } 473 }
402 474
403out: 475out:
476 afs_put_read(req);
404 _leave(" = %d", ret); 477 _leave(" = %d", ret);
405 return ret; 478 return ret;
406} 479}
@@ -414,23 +487,23 @@ static int afs_readdir(struct file *file, struct dir_context *ctx)
414} 487}
415 488
416/* 489/*
417 * search the directory for a name 490 * Search the directory for a single name
418 * - if afs_dir_iterate_block() spots this function, it'll pass the FID 491 * - if afs_dir_iterate_block() spots this function, it'll pass the FID
419 * uniquifier through dtype 492 * uniquifier through dtype
420 */ 493 */
421static int afs_lookup_filldir(struct dir_context *ctx, const char *name, 494static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
422 int nlen, loff_t fpos, u64 ino, unsigned dtype) 495 int nlen, loff_t fpos, u64 ino, unsigned dtype)
423{ 496{
424 struct afs_lookup_cookie *cookie = 497 struct afs_lookup_one_cookie *cookie =
425 container_of(ctx, struct afs_lookup_cookie, ctx); 498 container_of(ctx, struct afs_lookup_one_cookie, ctx);
426 499
427 _enter("{%s,%u},%s,%u,,%llu,%u", 500 _enter("{%s,%u},%s,%u,,%llu,%u",
428 cookie->name.name, cookie->name.len, name, nlen, 501 cookie->name.name, cookie->name.len, name, nlen,
429 (unsigned long long) ino, dtype); 502 (unsigned long long) ino, dtype);
430 503
431 /* insanity checks first */ 504 /* insanity checks first */
432 BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048); 505 BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);
433 BUILD_BUG_ON(sizeof(union afs_dirent) != 32); 506 BUILD_BUG_ON(sizeof(union afs_xdr_dirent) != 32);
434 507
435 if (cookie->name.len != nlen || 508 if (cookie->name.len != nlen ||
436 memcmp(cookie->name.name, name, nlen) != 0) { 509 memcmp(cookie->name.name, name, nlen) != 0) {
@@ -447,15 +520,15 @@ static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
447} 520}
448 521
449/* 522/*
450 * do a lookup in a directory 523 * Do a lookup of a single name in a directory
451 * - just returns the FID the dentry name maps to if found 524 * - just returns the FID the dentry name maps to if found
452 */ 525 */
453static int afs_do_lookup(struct inode *dir, struct dentry *dentry, 526static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry,
454 struct afs_fid *fid, struct key *key) 527 struct afs_fid *fid, struct key *key)
455{ 528{
456 struct afs_super_info *as = dir->i_sb->s_fs_info; 529 struct afs_super_info *as = dir->i_sb->s_fs_info;
457 struct afs_lookup_cookie cookie = { 530 struct afs_lookup_one_cookie cookie = {
458 .ctx.actor = afs_lookup_filldir, 531 .ctx.actor = afs_lookup_one_filldir,
459 .name = dentry->d_name, 532 .name = dentry->d_name,
460 .fid.vid = as->volume->vid 533 .fid.vid = as->volume->vid
461 }; 534 };
@@ -482,70 +555,265 @@ static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
482} 555}
483 556
484/* 557/*
485 * Probe to see if a cell may exist. This prevents positive dentries from 558 * search the directory for a name
486 * being created unnecessarily. 559 * - if afs_dir_iterate_block() spots this function, it'll pass the FID
560 * uniquifier through dtype
487 */ 561 */
488static int afs_probe_cell_name(struct dentry *dentry) 562static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
563 int nlen, loff_t fpos, u64 ino, unsigned dtype)
489{ 564{
490 struct afs_cell *cell; 565 struct afs_lookup_cookie *cookie =
491 const char *name = dentry->d_name.name; 566 container_of(ctx, struct afs_lookup_cookie, ctx);
492 size_t len = dentry->d_name.len;
493 int ret; 567 int ret;
494 568
495 /* Names prefixed with a dot are R/W mounts. */ 569 _enter("{%s,%u},%s,%u,,%llu,%u",
496 if (name[0] == '.') { 570 cookie->name.name, cookie->name.len, name, nlen,
497 if (len == 1) 571 (unsigned long long) ino, dtype);
498 return -EINVAL;
499 name++;
500 len--;
501 }
502 572
503 cell = afs_lookup_cell_rcu(afs_d2net(dentry), name, len); 573 /* insanity checks first */
504 if (!IS_ERR(cell)) { 574 BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);
505 afs_put_cell(afs_d2net(dentry), cell); 575 BUILD_BUG_ON(sizeof(union afs_xdr_dirent) != 32);
506 return 0; 576
577 if (cookie->found) {
578 if (cookie->nr_fids < 50) {
579 cookie->fids[cookie->nr_fids].vnode = ino;
580 cookie->fids[cookie->nr_fids].unique = dtype;
581 cookie->nr_fids++;
582 }
583 } else if (cookie->name.len == nlen &&
584 memcmp(cookie->name.name, name, nlen) == 0) {
585 cookie->fids[0].vnode = ino;
586 cookie->fids[0].unique = dtype;
587 cookie->found = 1;
588 if (cookie->one_only)
589 return -1;
507 } 590 }
508 591
509 ret = dns_query("afsdb", name, len, "ipv4", NULL, NULL); 592 ret = cookie->nr_fids >= 50 ? -1 : 0;
510 if (ret == -ENODATA) 593 _leave(" = %d", ret);
511 ret = -EDESTADDRREQ;
512 return ret; 594 return ret;
513} 595}
514 596
515/* 597/*
516 * Try to auto mount the mountpoint with pseudo directory, if the autocell 598 * Do a lookup in a directory. We make use of bulk lookup to query a slew of
517 * operation is setted. 599 * files in one go and create inodes for them. The inode of the file we were
600 * asked for is returned.
518 */ 601 */
519static struct inode *afs_try_auto_mntpt(struct dentry *dentry, 602static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
520 struct inode *dir, struct afs_fid *fid) 603 struct key *key)
521{ 604{
522 struct afs_vnode *vnode = AFS_FS_I(dir); 605 struct afs_lookup_cookie *cookie;
523 struct inode *inode; 606 struct afs_cb_interest *cbi = NULL;
524 int ret = -ENOENT; 607 struct afs_super_info *as = dir->i_sb->s_fs_info;
608 struct afs_iget_data data;
609 struct afs_fs_cursor fc;
610 struct afs_vnode *dvnode = AFS_FS_I(dir);
611 struct inode *inode = NULL;
612 int ret, i;
525 613
526 _enter("%p{%pd}, {%x:%u}", 614 _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry);
527 dentry, dentry, vnode->fid.vid, vnode->fid.vnode); 615
616 cookie = kzalloc(sizeof(struct afs_lookup_cookie), GFP_KERNEL);
617 if (!cookie)
618 return ERR_PTR(-ENOMEM);
619
620 cookie->ctx.actor = afs_lookup_filldir;
621 cookie->name = dentry->d_name;
622 cookie->nr_fids = 1; /* slot 0 is saved for the fid we actually want */
623
624 read_seqlock_excl(&dvnode->cb_lock);
625 if (dvnode->cb_interest &&
626 dvnode->cb_interest->server &&
627 test_bit(AFS_SERVER_FL_NO_IBULK, &dvnode->cb_interest->server->flags))
628 cookie->one_only = true;
629 read_sequnlock_excl(&dvnode->cb_lock);
630
631 for (i = 0; i < 50; i++)
632 cookie->fids[i].vid = as->volume->vid;
633
634 /* search the directory */
635 ret = afs_dir_iterate(dir, &cookie->ctx, key);
636 if (ret < 0) {
637 inode = ERR_PTR(ret);
638 goto out;
639 }
528 640
529 if (!test_bit(AFS_VNODE_AUTOCELL, &vnode->flags)) 641 inode = ERR_PTR(-ENOENT);
642 if (!cookie->found)
530 goto out; 643 goto out;
531 644
532 ret = afs_probe_cell_name(dentry); 645 /* Check to see if we already have an inode for the primary fid. */
533 if (ret < 0) 646 data.volume = dvnode->volume;
647 data.fid = cookie->fids[0];
648 inode = ilookup5(dir->i_sb, cookie->fids[0].vnode, afs_iget5_test, &data);
649 if (inode)
534 goto out; 650 goto out;
535 651
536 inode = afs_iget_pseudo_dir(dir->i_sb, false); 652 /* Need space for examining all the selected files */
537 if (IS_ERR(inode)) { 653 inode = ERR_PTR(-ENOMEM);
538 ret = PTR_ERR(inode); 654 cookie->statuses = kcalloc(cookie->nr_fids, sizeof(struct afs_file_status),
655 GFP_KERNEL);
656 if (!cookie->statuses)
539 goto out; 657 goto out;
658
659 cookie->callbacks = kcalloc(cookie->nr_fids, sizeof(struct afs_callback),
660 GFP_KERNEL);
661 if (!cookie->callbacks)
662 goto out_s;
663
664 /* Try FS.InlineBulkStatus first. Abort codes for the individual
665 * lookups contained therein are stored in the reply without aborting
666 * the whole operation.
667 */
668 if (cookie->one_only)
669 goto no_inline_bulk_status;
670
671 inode = ERR_PTR(-ERESTARTSYS);
672 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
673 while (afs_select_fileserver(&fc)) {
674 if (test_bit(AFS_SERVER_FL_NO_IBULK,
675 &fc.cbi->server->flags)) {
676 fc.ac.abort_code = RX_INVALID_OPERATION;
677 fc.ac.error = -ECONNABORTED;
678 break;
679 }
680 afs_fs_inline_bulk_status(&fc,
681 afs_v2net(dvnode),
682 cookie->fids,
683 cookie->statuses,
684 cookie->callbacks,
685 cookie->nr_fids, NULL);
686 }
687
688 if (fc.ac.error == 0)
689 cbi = afs_get_cb_interest(fc.cbi);
690 if (fc.ac.abort_code == RX_INVALID_OPERATION)
691 set_bit(AFS_SERVER_FL_NO_IBULK, &fc.cbi->server->flags);
692 inode = ERR_PTR(afs_end_vnode_operation(&fc));
540 } 693 }
541 694
542 *fid = AFS_FS_I(inode)->fid; 695 if (!IS_ERR(inode))
543 _leave("= %p", inode); 696 goto success;
544 return inode; 697 if (fc.ac.abort_code != RX_INVALID_OPERATION)
698 goto out_c;
699
700no_inline_bulk_status:
701 /* We could try FS.BulkStatus next, but this aborts the entire op if
702 * any of the lookups fails - so, for the moment, revert to
703 * FS.FetchStatus for just the primary fid.
704 */
705 cookie->nr_fids = 1;
706 inode = ERR_PTR(-ERESTARTSYS);
707 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
708 while (afs_select_fileserver(&fc)) {
709 afs_fs_fetch_status(&fc,
710 afs_v2net(dvnode),
711 cookie->fids,
712 cookie->statuses,
713 cookie->callbacks,
714 NULL);
715 }
716
717 if (fc.ac.error == 0)
718 cbi = afs_get_cb_interest(fc.cbi);
719 inode = ERR_PTR(afs_end_vnode_operation(&fc));
720 }
545 721
722 if (IS_ERR(inode))
723 goto out_c;
724
725 for (i = 0; i < cookie->nr_fids; i++)
726 cookie->statuses[i].abort_code = 0;
727
728success:
729 /* Turn all the files into inodes and save the first one - which is the
730 * one we actually want.
731 */
732 if (cookie->statuses[0].abort_code != 0)
733 inode = ERR_PTR(afs_abort_to_error(cookie->statuses[0].abort_code));
734
735 for (i = 0; i < cookie->nr_fids; i++) {
736 struct inode *ti;
737
738 if (cookie->statuses[i].abort_code != 0)
739 continue;
740
741 ti = afs_iget(dir->i_sb, key, &cookie->fids[i],
742 &cookie->statuses[i],
743 &cookie->callbacks[i],
744 cbi);
745 if (i == 0) {
746 inode = ti;
747 } else {
748 if (!IS_ERR(ti))
749 iput(ti);
750 }
751 }
752
753out_c:
754 afs_put_cb_interest(afs_v2net(dvnode), cbi);
755 kfree(cookie->callbacks);
756out_s:
757 kfree(cookie->statuses);
546out: 758out:
547 _leave("= %d", ret); 759 kfree(cookie);
548 return ERR_PTR(ret); 760 return inode;
761}
762
763/*
764 * Look up an entry in a directory with @sys substitution.
765 */
766static struct dentry *afs_lookup_atsys(struct inode *dir, struct dentry *dentry,
767 struct key *key)
768{
769 struct afs_sysnames *subs;
770 struct afs_net *net = afs_i2net(dir);
771 struct dentry *ret;
772 char *buf, *p, *name;
773 int len, i;
774
775 _enter("");
776
777 ret = ERR_PTR(-ENOMEM);
778 p = buf = kmalloc(AFSNAMEMAX, GFP_KERNEL);
779 if (!buf)
780 goto out_p;
781 if (dentry->d_name.len > 4) {
782 memcpy(p, dentry->d_name.name, dentry->d_name.len - 4);
783 p += dentry->d_name.len - 4;
784 }
785
786 /* There is an ordered list of substitutes that we have to try. */
787 read_lock(&net->sysnames_lock);
788 subs = net->sysnames;
789 refcount_inc(&subs->usage);
790 read_unlock(&net->sysnames_lock);
791
792 for (i = 0; i < subs->nr; i++) {
793 name = subs->subs[i];
794 len = dentry->d_name.len - 4 + strlen(name);
795 if (len >= AFSNAMEMAX) {
796 ret = ERR_PTR(-ENAMETOOLONG);
797 goto out_s;
798 }
799
800 strcpy(p, name);
801 ret = lookup_one_len(buf, dentry->d_parent, len);
802 if (IS_ERR(ret) || d_is_positive(ret))
803 goto out_s;
804 dput(ret);
805 }
806
807 /* We don't want to d_add() the @sys dentry here as we don't want to
808 * the cached dentry to hide changes to the sysnames list.
809 */
810 ret = NULL;
811out_s:
812 afs_put_sysnames(subs);
813 kfree(buf);
814out_p:
815 key_put(key);
816 return ret;
549} 817}
550 818
551/* 819/*
@@ -554,16 +822,13 @@ out:
554static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, 822static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
555 unsigned int flags) 823 unsigned int flags)
556{ 824{
557 struct afs_vnode *vnode; 825 struct afs_vnode *dvnode = AFS_FS_I(dir);
558 struct afs_fid fid;
559 struct inode *inode; 826 struct inode *inode;
560 struct key *key; 827 struct key *key;
561 int ret; 828 int ret;
562 829
563 vnode = AFS_FS_I(dir);
564
565 _enter("{%x:%u},%p{%pd},", 830 _enter("{%x:%u},%p{%pd},",
566 vnode->fid.vid, vnode->fid.vnode, dentry, dentry); 831 dvnode->fid.vid, dvnode->fid.vnode, dentry, dentry);
567 832
568 ASSERTCMP(d_inode(dentry), ==, NULL); 833 ASSERTCMP(d_inode(dentry), ==, NULL);
569 834
@@ -572,28 +837,37 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
572 return ERR_PTR(-ENAMETOOLONG); 837 return ERR_PTR(-ENAMETOOLONG);
573 } 838 }
574 839
575 if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { 840 if (test_bit(AFS_VNODE_DELETED, &dvnode->flags)) {
576 _leave(" = -ESTALE"); 841 _leave(" = -ESTALE");
577 return ERR_PTR(-ESTALE); 842 return ERR_PTR(-ESTALE);
578 } 843 }
579 844
580 key = afs_request_key(vnode->volume->cell); 845 key = afs_request_key(dvnode->volume->cell);
581 if (IS_ERR(key)) { 846 if (IS_ERR(key)) {
582 _leave(" = %ld [key]", PTR_ERR(key)); 847 _leave(" = %ld [key]", PTR_ERR(key));
583 return ERR_CAST(key); 848 return ERR_CAST(key);
584 } 849 }
585 850
586 ret = afs_validate(vnode, key); 851 ret = afs_validate(dvnode, key);
587 if (ret < 0) { 852 if (ret < 0) {
588 key_put(key); 853 key_put(key);
589 _leave(" = %d [val]", ret); 854 _leave(" = %d [val]", ret);
590 return ERR_PTR(ret); 855 return ERR_PTR(ret);
591 } 856 }
592 857
593 ret = afs_do_lookup(dir, dentry, &fid, key); 858 if (dentry->d_name.len >= 4 &&
594 if (ret < 0) { 859 dentry->d_name.name[dentry->d_name.len - 4] == '@' &&
860 dentry->d_name.name[dentry->d_name.len - 3] == 's' &&
861 dentry->d_name.name[dentry->d_name.len - 2] == 'y' &&
862 dentry->d_name.name[dentry->d_name.len - 1] == 's')
863 return afs_lookup_atsys(dir, dentry, key);
864
865 afs_stat_v(dvnode, n_lookup);
866 inode = afs_do_lookup(dir, dentry, key);
867 if (IS_ERR(inode)) {
868 ret = PTR_ERR(inode);
595 if (ret == -ENOENT) { 869 if (ret == -ENOENT) {
596 inode = afs_try_auto_mntpt(dentry, dir, &fid); 870 inode = afs_try_auto_mntpt(dentry, dir);
597 if (!IS_ERR(inode)) { 871 if (!IS_ERR(inode)) {
598 key_put(key); 872 key_put(key);
599 goto success; 873 goto success;
@@ -611,10 +885,9 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
611 _leave(" = %d [do]", ret); 885 _leave(" = %d [do]", ret);
612 return ERR_PTR(ret); 886 return ERR_PTR(ret);
613 } 887 }
614 dentry->d_fsdata = (void *)(unsigned long) vnode->status.data_version; 888 dentry->d_fsdata = (void *)(unsigned long)dvnode->status.data_version;
615 889
616 /* instantiate the dentry */ 890 /* instantiate the dentry */
617 inode = afs_iget(dir->i_sb, key, &fid, NULL, NULL, NULL);
618 key_put(key); 891 key_put(key);
619 if (IS_ERR(inode)) { 892 if (IS_ERR(inode)) {
620 _leave(" = %ld", PTR_ERR(inode)); 893 _leave(" = %ld", PTR_ERR(inode));
@@ -623,9 +896,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
623 896
624success: 897success:
625 d_add(dentry, inode); 898 d_add(dentry, inode);
626 _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%u }", 899 _leave(" = 0 { ino=%lu v=%u }",
627 fid.vnode,
628 fid.unique,
629 d_inode(dentry)->i_ino, 900 d_inode(dentry)->i_ino,
630 d_inode(dentry)->i_generation); 901 d_inode(dentry)->i_generation);
631 902
@@ -633,67 +904,23 @@ success:
633} 904}
634 905
635/* 906/*
636 * Look up an entry in a dynroot directory.
637 */
638static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry,
639 unsigned int flags)
640{
641 struct afs_vnode *vnode;
642 struct afs_fid fid;
643 struct inode *inode;
644 int ret;
645
646 vnode = AFS_FS_I(dir);
647
648 _enter("%pd", dentry);
649
650 ASSERTCMP(d_inode(dentry), ==, NULL);
651
652 if (dentry->d_name.len >= AFSNAMEMAX) {
653 _leave(" = -ENAMETOOLONG");
654 return ERR_PTR(-ENAMETOOLONG);
655 }
656
657 inode = afs_try_auto_mntpt(dentry, dir, &fid);
658 if (IS_ERR(inode)) {
659 ret = PTR_ERR(inode);
660 if (ret == -ENOENT) {
661 d_add(dentry, NULL);
662 _leave(" = NULL [negative]");
663 return NULL;
664 }
665 _leave(" = %d [do]", ret);
666 return ERR_PTR(ret);
667 }
668
669 d_add(dentry, inode);
670 _leave(" = 0 { ino=%lu v=%u }",
671 d_inode(dentry)->i_ino, d_inode(dentry)->i_generation);
672 return NULL;
673}
674
675/*
676 * check that a dentry lookup hit has found a valid entry 907 * check that a dentry lookup hit has found a valid entry
677 * - NOTE! the hit can be a negative hit too, so we can't assume we have an 908 * - NOTE! the hit can be a negative hit too, so we can't assume we have an
678 * inode 909 * inode
679 */ 910 */
680static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) 911static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
681{ 912{
682 struct afs_super_info *as = dentry->d_sb->s_fs_info;
683 struct afs_vnode *vnode, *dir; 913 struct afs_vnode *vnode, *dir;
684 struct afs_fid uninitialized_var(fid); 914 struct afs_fid uninitialized_var(fid);
685 struct dentry *parent; 915 struct dentry *parent;
686 struct inode *inode; 916 struct inode *inode;
687 struct key *key; 917 struct key *key;
688 void *dir_version; 918 long dir_version, de_version;
689 int ret; 919 int ret;
690 920
691 if (flags & LOOKUP_RCU) 921 if (flags & LOOKUP_RCU)
692 return -ECHILD; 922 return -ECHILD;
693 923
694 if (as->dyn_root)
695 return 1;
696
697 if (d_really_is_positive(dentry)) { 924 if (d_really_is_positive(dentry)) {
698 vnode = AFS_FS_I(d_inode(dentry)); 925 vnode = AFS_FS_I(d_inode(dentry));
699 _enter("{v={%x:%u} n=%pd fl=%lx},", 926 _enter("{v={%x:%u} n=%pd fl=%lx},",
@@ -729,14 +956,25 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
729 goto out_bad_parent; 956 goto out_bad_parent;
730 } 957 }
731 958
732 dir_version = (void *) (unsigned long) dir->status.data_version; 959 /* We only need to invalidate a dentry if the server's copy changed
733 if (dentry->d_fsdata == dir_version) 960 * behind our back. If we made the change, it's no problem. Note that
734 goto out_valid; /* the dir contents are unchanged */ 961 * on a 32-bit system, we only have 32 bits in the dentry to store the
962 * version.
963 */
964 dir_version = (long)dir->status.data_version;
965 de_version = (long)dentry->d_fsdata;
966 if (de_version == dir_version)
967 goto out_valid;
968
969 dir_version = (long)dir->invalid_before;
970 if (de_version - dir_version >= 0)
971 goto out_valid;
735 972
736 _debug("dir modified"); 973 _debug("dir modified");
974 afs_stat_v(dir, n_reval);
737 975
738 /* search the directory for this vnode */ 976 /* search the directory for this vnode */
739 ret = afs_do_lookup(&dir->vfs_inode, dentry, &fid, key); 977 ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key);
740 switch (ret) { 978 switch (ret) {
741 case 0: 979 case 0:
742 /* the filename maps to something */ 980 /* the filename maps to something */
@@ -789,7 +1027,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
789 } 1027 }
790 1028
791out_valid: 1029out_valid:
792 dentry->d_fsdata = dir_version; 1030 dentry->d_fsdata = (void *)dir_version;
793 dput(parent); 1031 dput(parent);
794 key_put(key); 1032 key_put(key);
795 _leave(" = 1 [valid]"); 1033 _leave(" = 1 [valid]");
@@ -840,7 +1078,7 @@ zap:
840/* 1078/*
841 * handle dentry release 1079 * handle dentry release
842 */ 1080 */
843static void afs_d_release(struct dentry *dentry) 1081void afs_d_release(struct dentry *dentry)
844{ 1082{
845 _enter("%pd", dentry); 1083 _enter("%pd", dentry);
846} 1084}
@@ -854,6 +1092,7 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
854 struct afs_file_status *newstatus, 1092 struct afs_file_status *newstatus,
855 struct afs_callback *newcb) 1093 struct afs_callback *newcb)
856{ 1094{
1095 struct afs_vnode *vnode;
857 struct inode *inode; 1096 struct inode *inode;
858 1097
859 if (fc->ac.error < 0) 1098 if (fc->ac.error < 0)
@@ -871,6 +1110,8 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
871 return; 1110 return;
872 } 1111 }
873 1112
1113 vnode = AFS_FS_I(inode);
1114 set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
874 d_add(new_dentry, inode); 1115 d_add(new_dentry, inode);
875} 1116}
876 1117
@@ -885,6 +1126,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
885 struct afs_vnode *dvnode = AFS_FS_I(dir); 1126 struct afs_vnode *dvnode = AFS_FS_I(dir);
886 struct afs_fid newfid; 1127 struct afs_fid newfid;
887 struct key *key; 1128 struct key *key;
1129 u64 data_version = dvnode->status.data_version;
888 int ret; 1130 int ret;
889 1131
890 mode |= S_IFDIR; 1132 mode |= S_IFDIR;
@@ -902,7 +1144,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
902 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1144 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
903 while (afs_select_fileserver(&fc)) { 1145 while (afs_select_fileserver(&fc)) {
904 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1146 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break;
905 afs_fs_create(&fc, dentry->d_name.name, mode, 1147 afs_fs_create(&fc, dentry->d_name.name, mode, data_version,
906 &newfid, &newstatus, &newcb); 1148 &newfid, &newstatus, &newcb);
907 } 1149 }
908 1150
@@ -916,6 +1158,11 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
916 goto error_key; 1158 goto error_key;
917 } 1159 }
918 1160
1161 if (ret == 0 &&
1162 test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
1163 afs_edit_dir_add(dvnode, &dentry->d_name, &newfid,
1164 afs_edit_dir_for_create);
1165
919 key_put(key); 1166 key_put(key);
920 _leave(" = 0"); 1167 _leave(" = 0");
921 return 0; 1168 return 0;
@@ -939,6 +1186,7 @@ static void afs_dir_remove_subdir(struct dentry *dentry)
939 clear_nlink(&vnode->vfs_inode); 1186 clear_nlink(&vnode->vfs_inode);
940 set_bit(AFS_VNODE_DELETED, &vnode->flags); 1187 set_bit(AFS_VNODE_DELETED, &vnode->flags);
941 clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 1188 clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
1189 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
942 } 1190 }
943} 1191}
944 1192
@@ -950,6 +1198,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
950 struct afs_fs_cursor fc; 1198 struct afs_fs_cursor fc;
951 struct afs_vnode *dvnode = AFS_FS_I(dir); 1199 struct afs_vnode *dvnode = AFS_FS_I(dir);
952 struct key *key; 1200 struct key *key;
1201 u64 data_version = dvnode->status.data_version;
953 int ret; 1202 int ret;
954 1203
955 _enter("{%x:%u},{%pd}", 1204 _enter("{%x:%u},{%pd}",
@@ -965,13 +1214,18 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
965 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1214 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
966 while (afs_select_fileserver(&fc)) { 1215 while (afs_select_fileserver(&fc)) {
967 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1216 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break;
968 afs_fs_remove(&fc, dentry->d_name.name, true); 1217 afs_fs_remove(&fc, dentry->d_name.name, true,
1218 data_version);
969 } 1219 }
970 1220
971 afs_vnode_commit_status(&fc, dvnode, fc.cb_break); 1221 afs_vnode_commit_status(&fc, dvnode, fc.cb_break);
972 ret = afs_end_vnode_operation(&fc); 1222 ret = afs_end_vnode_operation(&fc);
973 if (ret == 0) 1223 if (ret == 0) {
974 afs_dir_remove_subdir(dentry); 1224 afs_dir_remove_subdir(dentry);
1225 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
1226 afs_edit_dir_remove(dvnode, &dentry->d_name,
1227 afs_edit_dir_for_rmdir);
1228 }
975 } 1229 }
976 1230
977 key_put(key); 1231 key_put(key);
@@ -1036,6 +1290,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
1036 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode; 1290 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode;
1037 struct key *key; 1291 struct key *key;
1038 unsigned long d_version = (unsigned long)dentry->d_fsdata; 1292 unsigned long d_version = (unsigned long)dentry->d_fsdata;
1293 u64 data_version = dvnode->status.data_version;
1039 int ret; 1294 int ret;
1040 1295
1041 _enter("{%x:%u},{%pd}", 1296 _enter("{%x:%u},{%pd}",
@@ -1062,7 +1317,8 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
1062 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1317 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1063 while (afs_select_fileserver(&fc)) { 1318 while (afs_select_fileserver(&fc)) {
1064 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1319 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break;
1065 afs_fs_remove(&fc, dentry->d_name.name, false); 1320 afs_fs_remove(&fc, dentry->d_name.name, false,
1321 data_version);
1066 } 1322 }
1067 1323
1068 afs_vnode_commit_status(&fc, dvnode, fc.cb_break); 1324 afs_vnode_commit_status(&fc, dvnode, fc.cb_break);
@@ -1071,6 +1327,10 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
1071 ret = afs_dir_remove_link( 1327 ret = afs_dir_remove_link(
1072 dentry, key, d_version, 1328 dentry, key, d_version,
1073 (unsigned long)dvnode->status.data_version); 1329 (unsigned long)dvnode->status.data_version);
1330 if (ret == 0 &&
1331 test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
1332 afs_edit_dir_remove(dvnode, &dentry->d_name,
1333 afs_edit_dir_for_unlink);
1074 } 1334 }
1075 1335
1076error_key: 1336error_key:
@@ -1092,6 +1352,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
1092 struct afs_vnode *dvnode = AFS_FS_I(dir); 1352 struct afs_vnode *dvnode = AFS_FS_I(dir);
1093 struct afs_fid newfid; 1353 struct afs_fid newfid;
1094 struct key *key; 1354 struct key *key;
1355 u64 data_version = dvnode->status.data_version;
1095 int ret; 1356 int ret;
1096 1357
1097 mode |= S_IFREG; 1358 mode |= S_IFREG;
@@ -1113,7 +1374,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
1113 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1374 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1114 while (afs_select_fileserver(&fc)) { 1375 while (afs_select_fileserver(&fc)) {
1115 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1376 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break;
1116 afs_fs_create(&fc, dentry->d_name.name, mode, 1377 afs_fs_create(&fc, dentry->d_name.name, mode, data_version,
1117 &newfid, &newstatus, &newcb); 1378 &newfid, &newstatus, &newcb);
1118 } 1379 }
1119 1380
@@ -1127,6 +1388,10 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
1127 goto error_key; 1388 goto error_key;
1128 } 1389 }
1129 1390
1391 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
1392 afs_edit_dir_add(dvnode, &dentry->d_name, &newfid,
1393 afs_edit_dir_for_create);
1394
1130 key_put(key); 1395 key_put(key);
1131 _leave(" = 0"); 1396 _leave(" = 0");
1132 return 0; 1397 return 0;
@@ -1148,10 +1413,12 @@ static int afs_link(struct dentry *from, struct inode *dir,
1148 struct afs_fs_cursor fc; 1413 struct afs_fs_cursor fc;
1149 struct afs_vnode *dvnode, *vnode; 1414 struct afs_vnode *dvnode, *vnode;
1150 struct key *key; 1415 struct key *key;
1416 u64 data_version;
1151 int ret; 1417 int ret;
1152 1418
1153 vnode = AFS_FS_I(d_inode(from)); 1419 vnode = AFS_FS_I(d_inode(from));
1154 dvnode = AFS_FS_I(dir); 1420 dvnode = AFS_FS_I(dir);
1421 data_version = dvnode->status.data_version;
1155 1422
1156 _enter("{%x:%u},{%x:%u},{%pd}", 1423 _enter("{%x:%u},{%x:%u},{%pd}",
1157 vnode->fid.vid, vnode->fid.vnode, 1424 vnode->fid.vid, vnode->fid.vnode,
@@ -1178,7 +1445,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
1178 while (afs_select_fileserver(&fc)) { 1445 while (afs_select_fileserver(&fc)) {
1179 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1446 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break;
1180 fc.cb_break_2 = vnode->cb_break + vnode->cb_s_break; 1447 fc.cb_break_2 = vnode->cb_break + vnode->cb_s_break;
1181 afs_fs_link(&fc, vnode, dentry->d_name.name); 1448 afs_fs_link(&fc, vnode, dentry->d_name.name, data_version);
1182 } 1449 }
1183 1450
1184 afs_vnode_commit_status(&fc, dvnode, fc.cb_break); 1451 afs_vnode_commit_status(&fc, dvnode, fc.cb_break);
@@ -1194,6 +1461,10 @@ static int afs_link(struct dentry *from, struct inode *dir,
1194 goto error_key; 1461 goto error_key;
1195 } 1462 }
1196 1463
1464 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
1465 afs_edit_dir_add(dvnode, &dentry->d_name, &vnode->fid,
1466 afs_edit_dir_for_link);
1467
1197 key_put(key); 1468 key_put(key);
1198 _leave(" = 0"); 1469 _leave(" = 0");
1199 return 0; 1470 return 0;
@@ -1217,6 +1488,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
1217 struct afs_vnode *dvnode = AFS_FS_I(dir); 1488 struct afs_vnode *dvnode = AFS_FS_I(dir);
1218 struct afs_fid newfid; 1489 struct afs_fid newfid;
1219 struct key *key; 1490 struct key *key;
1491 u64 data_version = dvnode->status.data_version;
1220 int ret; 1492 int ret;
1221 1493
1222 _enter("{%x:%u},{%pd},%s", 1494 _enter("{%x:%u},{%pd},%s",
@@ -1241,7 +1513,8 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
1241 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1513 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1242 while (afs_select_fileserver(&fc)) { 1514 while (afs_select_fileserver(&fc)) {
1243 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1515 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break;
1244 afs_fs_symlink(&fc, dentry->d_name.name, content, 1516 afs_fs_symlink(&fc, dentry->d_name.name,
1517 content, data_version,
1245 &newfid, &newstatus); 1518 &newfid, &newstatus);
1246 } 1519 }
1247 1520
@@ -1255,6 +1528,10 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
1255 goto error_key; 1528 goto error_key;
1256 } 1529 }
1257 1530
1531 if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
1532 afs_edit_dir_add(dvnode, &dentry->d_name, &newfid,
1533 afs_edit_dir_for_symlink);
1534
1258 key_put(key); 1535 key_put(key);
1259 _leave(" = 0"); 1536 _leave(" = 0");
1260 return 0; 1537 return 0;
@@ -1277,6 +1554,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1277 struct afs_fs_cursor fc; 1554 struct afs_fs_cursor fc;
1278 struct afs_vnode *orig_dvnode, *new_dvnode, *vnode; 1555 struct afs_vnode *orig_dvnode, *new_dvnode, *vnode;
1279 struct key *key; 1556 struct key *key;
1557 u64 orig_data_version, new_data_version;
1558 bool new_negative = d_is_negative(new_dentry);
1280 int ret; 1559 int ret;
1281 1560
1282 if (flags) 1561 if (flags)
@@ -1285,6 +1564,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1285 vnode = AFS_FS_I(d_inode(old_dentry)); 1564 vnode = AFS_FS_I(d_inode(old_dentry));
1286 orig_dvnode = AFS_FS_I(old_dir); 1565 orig_dvnode = AFS_FS_I(old_dir);
1287 new_dvnode = AFS_FS_I(new_dir); 1566 new_dvnode = AFS_FS_I(new_dir);
1567 orig_data_version = orig_dvnode->status.data_version;
1568 new_data_version = new_dvnode->status.data_version;
1288 1569
1289 _enter("{%x:%u},{%x:%u},{%x:%u},{%pd}", 1570 _enter("{%x:%u},{%x:%u},{%x:%u},{%pd}",
1290 orig_dvnode->fid.vid, orig_dvnode->fid.vnode, 1571 orig_dvnode->fid.vid, orig_dvnode->fid.vnode,
@@ -1310,7 +1591,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1310 fc.cb_break = orig_dvnode->cb_break + orig_dvnode->cb_s_break; 1591 fc.cb_break = orig_dvnode->cb_break + orig_dvnode->cb_s_break;
1311 fc.cb_break_2 = new_dvnode->cb_break + new_dvnode->cb_s_break; 1592 fc.cb_break_2 = new_dvnode->cb_break + new_dvnode->cb_s_break;
1312 afs_fs_rename(&fc, old_dentry->d_name.name, 1593 afs_fs_rename(&fc, old_dentry->d_name.name,
1313 new_dvnode, new_dentry->d_name.name); 1594 new_dvnode, new_dentry->d_name.name,
1595 orig_data_version, new_data_version);
1314 } 1596 }
1315 1597
1316 afs_vnode_commit_status(&fc, orig_dvnode, fc.cb_break); 1598 afs_vnode_commit_status(&fc, orig_dvnode, fc.cb_break);
@@ -1322,9 +1604,68 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1322 goto error_key; 1604 goto error_key;
1323 } 1605 }
1324 1606
1607 if (ret == 0) {
1608 if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags))
1609 afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name,
1610 afs_edit_dir_for_rename);
1611
1612 if (!new_negative &&
1613 test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags))
1614 afs_edit_dir_remove(new_dvnode, &new_dentry->d_name,
1615 afs_edit_dir_for_rename);
1616
1617 if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags))
1618 afs_edit_dir_add(new_dvnode, &new_dentry->d_name,
1619 &vnode->fid, afs_edit_dir_for_rename);
1620 }
1621
1325error_key: 1622error_key:
1326 key_put(key); 1623 key_put(key);
1327error: 1624error:
1328 _leave(" = %d", ret); 1625 _leave(" = %d", ret);
1329 return ret; 1626 return ret;
1330} 1627}
1628
1629/*
1630 * Release a directory page and clean up its private state if it's not busy
1631 * - return true if the page can now be released, false if not
1632 */
1633static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags)
1634{
1635 struct afs_vnode *dvnode = AFS_FS_I(page->mapping->host);
1636
1637 _enter("{{%x:%u}[%lu]}", dvnode->fid.vid, dvnode->fid.vnode, page->index);
1638
1639 set_page_private(page, 0);
1640 ClearPagePrivate(page);
1641
1642 /* The directory will need reloading. */
1643 if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
1644 afs_stat_v(dvnode, n_relpg);
1645 return 1;
1646}
1647
1648/*
1649 * invalidate part or all of a page
1650 * - release a page and clean up its private data if offset is 0 (indicating
1651 * the entire page)
1652 */
1653static void afs_dir_invalidatepage(struct page *page, unsigned int offset,
1654 unsigned int length)
1655{
1656 struct afs_vnode *dvnode = AFS_FS_I(page->mapping->host);
1657
1658 _enter("{%lu},%u,%u", page->index, offset, length);
1659
1660 BUG_ON(!PageLocked(page));
1661
1662 /* The directory will need reloading. */
1663 if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
1664 afs_stat_v(dvnode, n_inval);
1665
1666 /* we clean up only if the entire page is being invalidated */
1667 if (offset == 0 && length == PAGE_SIZE) {
1668 set_page_private(page, 0);
1669 ClearPagePrivate(page);
1670 }
1671}
diff --git a/fs/afs/dir_edit.c b/fs/afs/dir_edit.c
new file mode 100644
index 000000000000..8b400f5aead5
--- /dev/null
+++ b/fs/afs/dir_edit.c
@@ -0,0 +1,505 @@
1/* AFS filesystem directory editing
2 *
3 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/fs.h>
14#include <linux/namei.h>
15#include <linux/pagemap.h>
16#include <linux/iversion.h>
17#include "internal.h"
18#include "xdr_fs.h"
19
20/*
21 * Find a number of contiguous clear bits in a directory block bitmask.
22 *
23 * There are 64 slots, which means we can load the entire bitmap into a
24 * variable. The first bit doesn't count as it corresponds to the block header
25 * slot. nr_slots is between 1 and 9.
26 */
27static int afs_find_contig_bits(union afs_xdr_dir_block *block, unsigned int nr_slots)
28{
29 u64 bitmap;
30 u32 mask;
31 int bit, n;
32
33 bitmap = (u64)block->hdr.bitmap[0] << 0 * 8;
34 bitmap |= (u64)block->hdr.bitmap[1] << 1 * 8;
35 bitmap |= (u64)block->hdr.bitmap[2] << 2 * 8;
36 bitmap |= (u64)block->hdr.bitmap[3] << 3 * 8;
37 bitmap |= (u64)block->hdr.bitmap[4] << 4 * 8;
38 bitmap |= (u64)block->hdr.bitmap[5] << 5 * 8;
39 bitmap |= (u64)block->hdr.bitmap[6] << 6 * 8;
40 bitmap |= (u64)block->hdr.bitmap[7] << 7 * 8;
41 bitmap >>= 1; /* The first entry is metadata */
42 bit = 1;
43 mask = (1 << nr_slots) - 1;
44
45 do {
46 if (sizeof(unsigned long) == 8)
47 n = ffz(bitmap);
48 else
49 n = ((u32)bitmap) != 0 ?
50 ffz((u32)bitmap) :
51 ffz((u32)(bitmap >> 32)) + 32;
52 bitmap >>= n;
53 bit += n;
54
55 if ((bitmap & mask) == 0) {
56 if (bit > 64 - nr_slots)
57 return -1;
58 return bit;
59 }
60
61 n = __ffs(bitmap);
62 bitmap >>= n;
63 bit += n;
64 } while (bitmap);
65
66 return -1;
67}
68
69/*
70 * Set a number of contiguous bits in the directory block bitmap.
71 */
72static void afs_set_contig_bits(union afs_xdr_dir_block *block,
73 int bit, unsigned int nr_slots)
74{
75 u64 mask, before, after;
76
77 mask = (1 << nr_slots) - 1;
78 mask <<= bit;
79
80 before = *(u64 *)block->hdr.bitmap;
81
82 block->hdr.bitmap[0] |= (u8)(mask >> 0 * 8);
83 block->hdr.bitmap[1] |= (u8)(mask >> 1 * 8);
84 block->hdr.bitmap[2] |= (u8)(mask >> 2 * 8);
85 block->hdr.bitmap[3] |= (u8)(mask >> 3 * 8);
86 block->hdr.bitmap[4] |= (u8)(mask >> 4 * 8);
87 block->hdr.bitmap[5] |= (u8)(mask >> 5 * 8);
88 block->hdr.bitmap[6] |= (u8)(mask >> 6 * 8);
89 block->hdr.bitmap[7] |= (u8)(mask >> 7 * 8);
90
91 after = *(u64 *)block->hdr.bitmap;
92}
93
94/*
95 * Clear a number of contiguous bits in the directory block bitmap.
96 */
97static void afs_clear_contig_bits(union afs_xdr_dir_block *block,
98 int bit, unsigned int nr_slots)
99{
100 u64 mask, before, after;
101
102 mask = (1 << nr_slots) - 1;
103 mask <<= bit;
104
105 before = *(u64 *)block->hdr.bitmap;
106
107 block->hdr.bitmap[0] &= ~(u8)(mask >> 0 * 8);
108 block->hdr.bitmap[1] &= ~(u8)(mask >> 1 * 8);
109 block->hdr.bitmap[2] &= ~(u8)(mask >> 2 * 8);
110 block->hdr.bitmap[3] &= ~(u8)(mask >> 3 * 8);
111 block->hdr.bitmap[4] &= ~(u8)(mask >> 4 * 8);
112 block->hdr.bitmap[5] &= ~(u8)(mask >> 5 * 8);
113 block->hdr.bitmap[6] &= ~(u8)(mask >> 6 * 8);
114 block->hdr.bitmap[7] &= ~(u8)(mask >> 7 * 8);
115
116 after = *(u64 *)block->hdr.bitmap;
117}
118
119/*
120 * Scan a directory block looking for a dirent of the right name.
121 */
122static int afs_dir_scan_block(union afs_xdr_dir_block *block, struct qstr *name,
123 unsigned int blocknum)
124{
125 union afs_xdr_dirent *de;
126 u64 bitmap;
127 int d, len, n;
128
129 _enter("");
130
131 bitmap = (u64)block->hdr.bitmap[0] << 0 * 8;
132 bitmap |= (u64)block->hdr.bitmap[1] << 1 * 8;
133 bitmap |= (u64)block->hdr.bitmap[2] << 2 * 8;
134 bitmap |= (u64)block->hdr.bitmap[3] << 3 * 8;
135 bitmap |= (u64)block->hdr.bitmap[4] << 4 * 8;
136 bitmap |= (u64)block->hdr.bitmap[5] << 5 * 8;
137 bitmap |= (u64)block->hdr.bitmap[6] << 6 * 8;
138 bitmap |= (u64)block->hdr.bitmap[7] << 7 * 8;
139
140 for (d = (blocknum == 0 ? AFS_DIR_RESV_BLOCKS0 : AFS_DIR_RESV_BLOCKS);
141 d < AFS_DIR_SLOTS_PER_BLOCK;
142 d++) {
143 if (!((bitmap >> d) & 1))
144 continue;
145 de = &block->dirents[d];
146 if (de->u.valid != 1)
147 continue;
148
149 /* The block was NUL-terminated by afs_dir_check_page(). */
150 len = strlen(de->u.name);
151 if (len == name->len &&
152 memcmp(de->u.name, name->name, name->len) == 0)
153 return d;
154
155 n = round_up(12 + len + 1 + 4, AFS_DIR_DIRENT_SIZE);
156 n /= AFS_DIR_DIRENT_SIZE;
157 d += n - 1;
158 }
159
160 return -1;
161}
162
163/*
164 * Initialise a new directory block. Note that block 0 is special and contains
165 * some extra metadata.
166 */
167static void afs_edit_init_block(union afs_xdr_dir_block *meta,
168 union afs_xdr_dir_block *block, int block_num)
169{
170 memset(block, 0, sizeof(*block));
171 block->hdr.npages = htons(1);
172 block->hdr.magic = AFS_DIR_MAGIC;
173 block->hdr.bitmap[0] = 1;
174
175 if (block_num == 0) {
176 block->hdr.bitmap[0] = 0xff;
177 block->hdr.bitmap[1] = 0x1f;
178 memset(block->meta.alloc_ctrs,
179 AFS_DIR_SLOTS_PER_BLOCK,
180 sizeof(block->meta.alloc_ctrs));
181 meta->meta.alloc_ctrs[0] =
182 AFS_DIR_SLOTS_PER_BLOCK - AFS_DIR_RESV_BLOCKS0;
183 }
184
185 if (block_num < AFS_DIR_BLOCKS_WITH_CTR)
186 meta->meta.alloc_ctrs[block_num] =
187 AFS_DIR_SLOTS_PER_BLOCK - AFS_DIR_RESV_BLOCKS;
188}
189
190/*
191 * Edit a directory's file data to add a new directory entry. Doing this after
192 * create, mkdir, symlink, link or rename if the data version number is
193 * incremented by exactly one avoids the need to re-download the entire
194 * directory contents.
195 *
196 * The caller must hold the inode locked.
197 */
198void afs_edit_dir_add(struct afs_vnode *vnode,
199 struct qstr *name, struct afs_fid *new_fid,
200 enum afs_edit_dir_reason why)
201{
202 union afs_xdr_dir_block *meta, *block;
203 struct afs_xdr_dir_page *meta_page, *dir_page;
204 union afs_xdr_dirent *de;
205 struct page *page0, *page;
206 unsigned int need_slots, nr_blocks, b;
207 pgoff_t index;
208 loff_t i_size;
209 gfp_t gfp;
210 int slot;
211
212 _enter(",,{%d,%s},", name->len, name->name);
213
214 i_size = i_size_read(&vnode->vfs_inode);
215 if (i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS ||
216 (i_size & (AFS_DIR_BLOCK_SIZE - 1))) {
217 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
218 return;
219 }
220
221 gfp = vnode->vfs_inode.i_mapping->gfp_mask;
222 page0 = find_or_create_page(vnode->vfs_inode.i_mapping, 0, gfp);
223 if (!page0) {
224 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
225 _leave(" [fgp]");
226 return;
227 }
228
229 /* Work out how many slots we're going to need. */
230 need_slots = round_up(12 + name->len + 1 + 4, AFS_DIR_DIRENT_SIZE);
231 need_slots /= AFS_DIR_DIRENT_SIZE;
232
233 meta_page = kmap(page0);
234 meta = &meta_page->blocks[0];
235 if (i_size == 0)
236 goto new_directory;
237 nr_blocks = i_size / AFS_DIR_BLOCK_SIZE;
238
239 /* Find a block that has sufficient slots available. Each VM page
240 * contains two or more directory blocks.
241 */
242 for (b = 0; b < nr_blocks + 1; b++) {
243 /* If the directory extended into a new page, then we need to
244 * tack a new page on the end.
245 */
246 index = b / AFS_DIR_BLOCKS_PER_PAGE;
247 if (index == 0) {
248 page = page0;
249 dir_page = meta_page;
250 } else {
251 if (nr_blocks >= AFS_DIR_MAX_BLOCKS)
252 goto error;
253 gfp = vnode->vfs_inode.i_mapping->gfp_mask;
254 page = find_or_create_page(vnode->vfs_inode.i_mapping,
255 index, gfp);
256 if (!page)
257 goto error;
258 if (!PagePrivate(page)) {
259 set_page_private(page, 1);
260 SetPagePrivate(page);
261 }
262 dir_page = kmap(page);
263 }
264
265 /* Abandon the edit if we got a callback break. */
266 if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
267 goto invalidated;
268
269 block = &dir_page->blocks[b % AFS_DIR_BLOCKS_PER_PAGE];
270
271 _debug("block %u: %2u %3u %u",
272 b,
273 (b < AFS_DIR_BLOCKS_WITH_CTR) ? meta->meta.alloc_ctrs[b] : 99,
274 ntohs(block->hdr.npages),
275 ntohs(block->hdr.magic));
276
277 /* Initialise the block if necessary. */
278 if (b == nr_blocks) {
279 _debug("init %u", b);
280 afs_edit_init_block(meta, block, b);
281 i_size_write(&vnode->vfs_inode, (b + 1) * AFS_DIR_BLOCK_SIZE);
282 }
283
284 /* Only lower dir pages have a counter in the header. */
285 if (b >= AFS_DIR_BLOCKS_WITH_CTR ||
286 meta->meta.alloc_ctrs[b] >= need_slots) {
287 /* We need to try and find one or more consecutive
288 * slots to hold the entry.
289 */
290 slot = afs_find_contig_bits(block, need_slots);
291 if (slot >= 0) {
292 _debug("slot %u", slot);
293 goto found_space;
294 }
295 }
296
297 if (page != page0) {
298 unlock_page(page);
299 kunmap(page);
300 put_page(page);
301 }
302 }
303
304 /* There are no spare slots of sufficient size, yet the operation
305 * succeeded. Download the directory again.
306 */
307 trace_afs_edit_dir(vnode, why, afs_edit_dir_create_nospc, 0, 0, 0, 0, name->name);
308 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
309 goto out_unmap;
310
311new_directory:
312 afs_edit_init_block(meta, meta, 0);
313 i_size = AFS_DIR_BLOCK_SIZE;
314 i_size_write(&vnode->vfs_inode, i_size);
315 slot = AFS_DIR_RESV_BLOCKS0;
316 page = page0;
317 block = meta;
318 nr_blocks = 1;
319 b = 0;
320
321found_space:
322 /* Set the dirent slot. */
323 trace_afs_edit_dir(vnode, why, afs_edit_dir_create, b, slot,
324 new_fid->vnode, new_fid->unique, name->name);
325 de = &block->dirents[slot];
326 de->u.valid = 1;
327 de->u.unused[0] = 0;
328 de->u.hash_next = 0; // TODO: Really need to maintain this
329 de->u.vnode = htonl(new_fid->vnode);
330 de->u.unique = htonl(new_fid->unique);
331 memcpy(de->u.name, name->name, name->len + 1);
332 de->u.name[name->len] = 0;
333
334 /* Adjust the bitmap. */
335 afs_set_contig_bits(block, slot, need_slots);
336 if (page != page0) {
337 unlock_page(page);
338 kunmap(page);
339 put_page(page);
340 }
341
342 /* Adjust the allocation counter. */
343 if (b < AFS_DIR_BLOCKS_WITH_CTR)
344 meta->meta.alloc_ctrs[b] -= need_slots;
345
346 inode_inc_iversion_raw(&vnode->vfs_inode);
347 afs_stat_v(vnode, n_dir_cr);
348 _debug("Insert %s in %u[%u]", name->name, b, slot);
349
350out_unmap:
351 unlock_page(page0);
352 kunmap(page0);
353 put_page(page0);
354 _leave("");
355 return;
356
357invalidated:
358 trace_afs_edit_dir(vnode, why, afs_edit_dir_create_inval, 0, 0, 0, 0, name->name);
359 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
360 if (page != page0) {
361 kunmap(page);
362 put_page(page);
363 }
364 goto out_unmap;
365
366error:
367 trace_afs_edit_dir(vnode, why, afs_edit_dir_create_error, 0, 0, 0, 0, name->name);
368 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
369 goto out_unmap;
370}
371
372/*
373 * Edit a directory's file data to remove a new directory entry. Doing this
374 * after unlink, rmdir or rename if the data version number is incremented by
375 * exactly one avoids the need to re-download the entire directory contents.
376 *
377 * The caller must hold the inode locked.
378 */
379void afs_edit_dir_remove(struct afs_vnode *vnode,
380 struct qstr *name, enum afs_edit_dir_reason why)
381{
382 struct afs_xdr_dir_page *meta_page, *dir_page;
383 union afs_xdr_dir_block *meta, *block;
384 union afs_xdr_dirent *de;
385 struct page *page0, *page;
386 unsigned int need_slots, nr_blocks, b;
387 pgoff_t index;
388 loff_t i_size;
389 int slot;
390
391 _enter(",,{%d,%s},", name->len, name->name);
392
393 i_size = i_size_read(&vnode->vfs_inode);
394 if (i_size < AFS_DIR_BLOCK_SIZE ||
395 i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS ||
396 (i_size & (AFS_DIR_BLOCK_SIZE - 1))) {
397 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
398 return;
399 }
400 nr_blocks = i_size / AFS_DIR_BLOCK_SIZE;
401
402 page0 = find_lock_page(vnode->vfs_inode.i_mapping, 0);
403 if (!page0) {
404 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
405 _leave(" [fgp]");
406 return;
407 }
408
409 /* Work out how many slots we're going to discard. */
410 need_slots = round_up(12 + name->len + 1 + 4, AFS_DIR_DIRENT_SIZE);
411 need_slots /= AFS_DIR_DIRENT_SIZE;
412
413 meta_page = kmap(page0);
414 meta = &meta_page->blocks[0];
415
416 /* Find a page that has sufficient slots available. Each VM page
417 * contains two or more directory blocks.
418 */
419 for (b = 0; b < nr_blocks; b++) {
420 index = b / AFS_DIR_BLOCKS_PER_PAGE;
421 if (index != 0) {
422 page = find_lock_page(vnode->vfs_inode.i_mapping, index);
423 if (!page)
424 goto error;
425 dir_page = kmap(page);
426 } else {
427 page = page0;
428 dir_page = meta_page;
429 }
430
431 /* Abandon the edit if we got a callback break. */
432 if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
433 goto invalidated;
434
435 block = &dir_page->blocks[b % AFS_DIR_BLOCKS_PER_PAGE];
436
437 if (b > AFS_DIR_BLOCKS_WITH_CTR ||
438 meta->meta.alloc_ctrs[b] <= AFS_DIR_SLOTS_PER_BLOCK - 1 - need_slots) {
439 slot = afs_dir_scan_block(block, name, b);
440 if (slot >= 0)
441 goto found_dirent;
442 }
443
444 if (page != page0) {
445 unlock_page(page);
446 kunmap(page);
447 put_page(page);
448 }
449 }
450
451 /* Didn't find the dirent to clobber. Download the directory again. */
452 trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_noent,
453 0, 0, 0, 0, name->name);
454 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
455 goto out_unmap;
456
457found_dirent:
458 de = &block->dirents[slot];
459
460 trace_afs_edit_dir(vnode, why, afs_edit_dir_delete, b, slot,
461 ntohl(de->u.vnode), ntohl(de->u.unique),
462 name->name);
463
464 memset(de, 0, sizeof(*de) * need_slots);
465
466 /* Adjust the bitmap. */
467 afs_clear_contig_bits(block, slot, need_slots);
468 if (page != page0) {
469 unlock_page(page);
470 kunmap(page);
471 put_page(page);
472 }
473
474 /* Adjust the allocation counter. */
475 if (b < AFS_DIR_BLOCKS_WITH_CTR)
476 meta->meta.alloc_ctrs[b] += need_slots;
477
478 inode_set_iversion_raw(&vnode->vfs_inode, vnode->status.data_version);
479 afs_stat_v(vnode, n_dir_rm);
480 _debug("Remove %s from %u[%u]", name->name, b, slot);
481
482out_unmap:
483 unlock_page(page0);
484 kunmap(page0);
485 put_page(page0);
486 _leave("");
487 return;
488
489invalidated:
490 trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_inval,
491 0, 0, 0, 0, name->name);
492 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
493 if (page != page0) {
494 unlock_page(page);
495 kunmap(page);
496 put_page(page);
497 }
498 goto out_unmap;
499
500error:
501 trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_error,
502 0, 0, 0, 0, name->name);
503 clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
504 goto out_unmap;
505}
diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c
new file mode 100644
index 000000000000..983f3946ab57
--- /dev/null
+++ b/fs/afs/dynroot.c
@@ -0,0 +1,209 @@
1/* dir.c: AFS dynamic root handling
2 *
3 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/fs.h>
13#include <linux/namei.h>
14#include <linux/dns_resolver.h>
15#include "internal.h"
16
17const struct file_operations afs_dynroot_file_operations = {
18 .open = dcache_dir_open,
19 .release = dcache_dir_close,
20 .iterate_shared = dcache_readdir,
21 .llseek = dcache_dir_lseek,
22};
23
24/*
25 * Probe to see if a cell may exist. This prevents positive dentries from
26 * being created unnecessarily.
27 */
28static int afs_probe_cell_name(struct dentry *dentry)
29{
30 struct afs_cell *cell;
31 const char *name = dentry->d_name.name;
32 size_t len = dentry->d_name.len;
33 int ret;
34
35 /* Names prefixed with a dot are R/W mounts. */
36 if (name[0] == '.') {
37 if (len == 1)
38 return -EINVAL;
39 name++;
40 len--;
41 }
42
43 cell = afs_lookup_cell_rcu(afs_d2net(dentry), name, len);
44 if (!IS_ERR(cell)) {
45 afs_put_cell(afs_d2net(dentry), cell);
46 return 0;
47 }
48
49 ret = dns_query("afsdb", name, len, "ipv4", NULL, NULL);
50 if (ret == -ENODATA)
51 ret = -EDESTADDRREQ;
52 return ret;
53}
54
55/*
56 * Try to auto mount the mountpoint with pseudo directory, if the autocell
57 * operation is setted.
58 */
59struct inode *afs_try_auto_mntpt(struct dentry *dentry, struct inode *dir)
60{
61 struct afs_vnode *vnode = AFS_FS_I(dir);
62 struct inode *inode;
63 int ret = -ENOENT;
64
65 _enter("%p{%pd}, {%x:%u}",
66 dentry, dentry, vnode->fid.vid, vnode->fid.vnode);
67
68 if (!test_bit(AFS_VNODE_AUTOCELL, &vnode->flags))
69 goto out;
70
71 ret = afs_probe_cell_name(dentry);
72 if (ret < 0)
73 goto out;
74
75 inode = afs_iget_pseudo_dir(dir->i_sb, false);
76 if (IS_ERR(inode)) {
77 ret = PTR_ERR(inode);
78 goto out;
79 }
80
81 _leave("= %p", inode);
82 return inode;
83
84out:
85 _leave("= %d", ret);
86 return ERR_PTR(ret);
87}
88
89/*
90 * Look up @cell in a dynroot directory. This is a substitution for the
91 * local cell name for the net namespace.
92 */
93static struct dentry *afs_lookup_atcell(struct dentry *dentry)
94{
95 struct afs_cell *cell;
96 struct afs_net *net = afs_d2net(dentry);
97 struct dentry *ret;
98 unsigned int seq = 0;
99 char *name;
100 int len;
101
102 if (!net->ws_cell)
103 return ERR_PTR(-ENOENT);
104
105 ret = ERR_PTR(-ENOMEM);
106 name = kmalloc(AFS_MAXCELLNAME + 1, GFP_KERNEL);
107 if (!name)
108 goto out_p;
109
110 rcu_read_lock();
111 do {
112 read_seqbegin_or_lock(&net->cells_lock, &seq);
113 cell = rcu_dereference_raw(net->ws_cell);
114 if (cell) {
115 len = cell->name_len;
116 memcpy(name, cell->name, len + 1);
117 }
118 } while (need_seqretry(&net->cells_lock, seq));
119 done_seqretry(&net->cells_lock, seq);
120 rcu_read_unlock();
121
122 ret = ERR_PTR(-ENOENT);
123 if (!cell)
124 goto out_n;
125
126 ret = lookup_one_len(name, dentry->d_parent, len);
127
128 /* We don't want to d_add() the @cell dentry here as we don't want to
129 * the cached dentry to hide changes to the local cell name.
130 */
131
132out_n:
133 kfree(name);
134out_p:
135 return ret;
136}
137
138/*
139 * Look up an entry in a dynroot directory.
140 */
141static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry,
142 unsigned int flags)
143{
144 struct afs_vnode *vnode;
145 struct inode *inode;
146 int ret;
147
148 vnode = AFS_FS_I(dir);
149
150 _enter("%pd", dentry);
151
152 ASSERTCMP(d_inode(dentry), ==, NULL);
153
154 if (dentry->d_name.len >= AFSNAMEMAX) {
155 _leave(" = -ENAMETOOLONG");
156 return ERR_PTR(-ENAMETOOLONG);
157 }
158
159 if (dentry->d_name.len == 5 &&
160 memcmp(dentry->d_name.name, "@cell", 5) == 0)
161 return afs_lookup_atcell(dentry);
162
163 inode = afs_try_auto_mntpt(dentry, dir);
164 if (IS_ERR(inode)) {
165 ret = PTR_ERR(inode);
166 if (ret == -ENOENT) {
167 d_add(dentry, NULL);
168 _leave(" = NULL [negative]");
169 return NULL;
170 }
171 _leave(" = %d [do]", ret);
172 return ERR_PTR(ret);
173 }
174
175 d_add(dentry, inode);
176 _leave(" = 0 { ino=%lu v=%u }",
177 d_inode(dentry)->i_ino, d_inode(dentry)->i_generation);
178 return NULL;
179}
180
181const struct inode_operations afs_dynroot_inode_operations = {
182 .lookup = afs_dynroot_lookup,
183};
184
185/*
186 * Dirs in the dynamic root don't need revalidation.
187 */
188static int afs_dynroot_d_revalidate(struct dentry *dentry, unsigned int flags)
189{
190 return 1;
191}
192
193/*
194 * Allow the VFS to enquire as to whether a dentry should be unhashed (mustn't
195 * sleep)
196 * - called from dput() when d_count is going to 0.
197 * - return 1 to request dentry be unhashed, 0 otherwise
198 */
199static int afs_dynroot_d_delete(const struct dentry *dentry)
200{
201 return d_really_is_positive(dentry);
202}
203
204const struct dentry_operations afs_dynroot_dentry_operations = {
205 .d_revalidate = afs_dynroot_d_revalidate,
206 .d_delete = afs_dynroot_d_delete,
207 .d_release = afs_d_release,
208 .d_automount = afs_d_automount,
209};
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 79e665a35fea..c24c08016dd9 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -30,7 +30,6 @@ static int afs_readpages(struct file *filp, struct address_space *mapping,
30 30
31const struct file_operations afs_file_operations = { 31const struct file_operations afs_file_operations = {
32 .open = afs_open, 32 .open = afs_open,
33 .flush = afs_flush,
34 .release = afs_release, 33 .release = afs_release,
35 .llseek = generic_file_llseek, 34 .llseek = generic_file_llseek,
36 .read_iter = generic_file_read_iter, 35 .read_iter = generic_file_read_iter,
@@ -146,6 +145,9 @@ int afs_open(struct inode *inode, struct file *file)
146 if (ret < 0) 145 if (ret < 0)
147 goto error_af; 146 goto error_af;
148 } 147 }
148
149 if (file->f_flags & O_TRUNC)
150 set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
149 151
150 file->private_data = af; 152 file->private_data = af;
151 _leave(" = 0"); 153 _leave(" = 0");
@@ -170,6 +172,9 @@ int afs_release(struct inode *inode, struct file *file)
170 172
171 _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode); 173 _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);
172 174
175 if ((file->f_mode & FMODE_WRITE))
176 return vfs_fsync(file, 0);
177
173 file->private_data = NULL; 178 file->private_data = NULL;
174 if (af->wb) 179 if (af->wb)
175 afs_put_wb_key(af->wb); 180 afs_put_wb_key(af->wb);
@@ -187,10 +192,12 @@ void afs_put_read(struct afs_read *req)
187{ 192{
188 int i; 193 int i;
189 194
190 if (atomic_dec_and_test(&req->usage)) { 195 if (refcount_dec_and_test(&req->usage)) {
191 for (i = 0; i < req->nr_pages; i++) 196 for (i = 0; i < req->nr_pages; i++)
192 if (req->pages[i]) 197 if (req->pages[i])
193 put_page(req->pages[i]); 198 put_page(req->pages[i]);
199 if (req->pages != req->array)
200 kfree(req->pages);
194 kfree(req); 201 kfree(req);
195 } 202 }
196} 203}
@@ -240,6 +247,12 @@ int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *de
240 ret = afs_end_vnode_operation(&fc); 247 ret = afs_end_vnode_operation(&fc);
241 } 248 }
242 249
250 if (ret == 0) {
251 afs_stat_v(vnode, n_fetches);
252 atomic_long_add(desc->actual_len,
253 &afs_v2net(vnode)->n_fetch_bytes);
254 }
255
243 _leave(" = %d", ret); 256 _leave(" = %d", ret);
244 return ret; 257 return ret;
245} 258}
@@ -297,10 +310,11 @@ int afs_page_filler(void *data, struct page *page)
297 * end of the file, the server will return a short read and the 310 * end of the file, the server will return a short read and the
298 * unmarshalling code will clear the unfilled space. 311 * unmarshalling code will clear the unfilled space.
299 */ 312 */
300 atomic_set(&req->usage, 1); 313 refcount_set(&req->usage, 1);
301 req->pos = (loff_t)page->index << PAGE_SHIFT; 314 req->pos = (loff_t)page->index << PAGE_SHIFT;
302 req->len = PAGE_SIZE; 315 req->len = PAGE_SIZE;
303 req->nr_pages = 1; 316 req->nr_pages = 1;
317 req->pages = req->array;
304 req->pages[0] = page; 318 req->pages[0] = page;
305 get_page(page); 319 get_page(page);
306 320
@@ -309,10 +323,6 @@ int afs_page_filler(void *data, struct page *page)
309 ret = afs_fetch_data(vnode, key, req); 323 ret = afs_fetch_data(vnode, key, req);
310 afs_put_read(req); 324 afs_put_read(req);
311 325
312 if (ret >= 0 && S_ISDIR(inode->i_mode) &&
313 !afs_dir_check_page(inode, page))
314 ret = -EIO;
315
316 if (ret < 0) { 326 if (ret < 0) {
317 if (ret == -ENOENT) { 327 if (ret == -ENOENT) {
318 _debug("got NOENT from server" 328 _debug("got NOENT from server"
@@ -447,10 +457,11 @@ static int afs_readpages_one(struct file *file, struct address_space *mapping,
447 if (!req) 457 if (!req)
448 return -ENOMEM; 458 return -ENOMEM;
449 459
450 atomic_set(&req->usage, 1); 460 refcount_set(&req->usage, 1);
451 req->page_done = afs_readpages_page_done; 461 req->page_done = afs_readpages_page_done;
452 req->pos = first->index; 462 req->pos = first->index;
453 req->pos <<= PAGE_SHIFT; 463 req->pos <<= PAGE_SHIFT;
464 req->pages = req->array;
454 465
455 /* Transfer the pages to the request. We add them in until one fails 466 /* Transfer the pages to the request. We add them in until one fails
456 * to add to the LRU and then we stop (as that'll make a hole in the 467 * to add to the LRU and then we stop (as that'll make a hole in the
diff --git a/fs/afs/flock.c b/fs/afs/flock.c
index c40ba2fe3cbe..7a0e017070ec 100644
--- a/fs/afs/flock.c
+++ b/fs/afs/flock.c
@@ -613,7 +613,7 @@ static int afs_do_getlk(struct file *file, struct file_lock *fl)
613 posix_test_lock(file, fl); 613 posix_test_lock(file, fl);
614 if (fl->fl_type == F_UNLCK) { 614 if (fl->fl_type == F_UNLCK) {
615 /* no local locks; consult the server */ 615 /* no local locks; consult the server */
616 ret = afs_fetch_status(vnode, key); 616 ret = afs_fetch_status(vnode, key, false);
617 if (ret < 0) 617 if (ret < 0)
618 goto error; 618 goto error;
619 619
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 88ec38c2d83c..efacdb7c1dee 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -16,6 +16,7 @@
16#include <linux/iversion.h> 16#include <linux/iversion.h>
17#include "internal.h" 17#include "internal.h"
18#include "afs_fs.h" 18#include "afs_fs.h"
19#include "xdr_fs.h"
19 20
20static const struct afs_fid afs_zero_fid; 21static const struct afs_fid afs_zero_fid;
21 22
@@ -44,109 +45,194 @@ static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
44} 45}
45 46
46/* 47/*
47 * decode an AFSFetchStatus block 48 * Dump a bad file status record.
48 */ 49 */
49static void xdr_decode_AFSFetchStatus(const __be32 **_bp, 50static void xdr_dump_bad(const __be32 *bp)
50 struct afs_file_status *status,
51 struct afs_vnode *vnode,
52 afs_dataversion_t *store_version)
53{ 51{
54 afs_dataversion_t expected_version; 52 __be32 x[4];
55 const __be32 *bp = *_bp; 53 int i;
54
55 pr_notice("AFS XDR: Bad status record\n");
56 for (i = 0; i < 5 * 4 * 4; i += 16) {
57 memcpy(x, bp, 16);
58 bp += 4;
59 pr_notice("%03x: %08x %08x %08x %08x\n",
60 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
61 }
62
63 memcpy(x, bp, 4);
64 pr_notice("0x50: %08x\n", ntohl(x[0]));
65}
66
67/*
68 * Update the core inode struct from a returned status record.
69 */
70void afs_update_inode_from_status(struct afs_vnode *vnode,
71 struct afs_file_status *status,
72 const afs_dataversion_t *expected_version,
73 u8 flags)
74{
75 struct timespec t;
56 umode_t mode; 76 umode_t mode;
77
78 t.tv_sec = status->mtime_client;
79 t.tv_nsec = 0;
80 vnode->vfs_inode.i_ctime = t;
81 vnode->vfs_inode.i_mtime = t;
82 vnode->vfs_inode.i_atime = t;
83
84 if (flags & (AFS_VNODE_META_CHANGED | AFS_VNODE_NOT_YET_SET)) {
85 vnode->vfs_inode.i_uid = make_kuid(&init_user_ns, status->owner);
86 vnode->vfs_inode.i_gid = make_kgid(&init_user_ns, status->group);
87 set_nlink(&vnode->vfs_inode, status->nlink);
88
89 mode = vnode->vfs_inode.i_mode;
90 mode &= ~S_IALLUGO;
91 mode |= status->mode;
92 barrier();
93 vnode->vfs_inode.i_mode = mode;
94 }
95
96 if (!(flags & AFS_VNODE_NOT_YET_SET)) {
97 if (expected_version &&
98 *expected_version != status->data_version) {
99 _debug("vnode modified %llx on {%x:%u} [exp %llx]",
100 (unsigned long long) status->data_version,
101 vnode->fid.vid, vnode->fid.vnode,
102 (unsigned long long) *expected_version);
103 vnode->invalid_before = status->data_version;
104 if (vnode->status.type == AFS_FTYPE_DIR) {
105 if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
106 afs_stat_v(vnode, n_inval);
107 } else {
108 set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
109 }
110 } else if (vnode->status.type == AFS_FTYPE_DIR) {
111 /* Expected directory change is handled elsewhere so
112 * that we can locally edit the directory and save on a
113 * download.
114 */
115 if (test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
116 flags &= ~AFS_VNODE_DATA_CHANGED;
117 }
118 }
119
120 if (flags & (AFS_VNODE_DATA_CHANGED | AFS_VNODE_NOT_YET_SET)) {
121 inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
122 i_size_write(&vnode->vfs_inode, status->size);
123 }
124}
125
126/*
127 * decode an AFSFetchStatus block
128 */
129static int xdr_decode_AFSFetchStatus(struct afs_call *call,
130 const __be32 **_bp,
131 struct afs_file_status *status,
132 struct afs_vnode *vnode,
133 const afs_dataversion_t *expected_version,
134 struct afs_read *read_req)
135{
136 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;
57 u64 data_version, size; 137 u64 data_version, size;
58 bool changed = false; 138 u32 type, abort_code;
59 kuid_t owner; 139 u8 flags = 0;
60 kgid_t group; 140 int ret;
61 141
62 if (vnode) 142 if (vnode)
63 write_seqlock(&vnode->cb_lock); 143 write_seqlock(&vnode->cb_lock);
64 144
65#define EXTRACT(DST) \ 145 if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) {
66 do { \ 146 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
67 u32 x = ntohl(*bp++); \ 147 goto bad;
68 if (DST != x) \ 148 }
69 changed |= true; \
70 DST = x; \
71 } while (0)
72
73 status->if_version = ntohl(*bp++);
74 EXTRACT(status->type);
75 EXTRACT(status->nlink);
76 size = ntohl(*bp++);
77 data_version = ntohl(*bp++);
78 EXTRACT(status->author);
79 owner = make_kuid(&init_user_ns, ntohl(*bp++));
80 changed |= !uid_eq(owner, status->owner);
81 status->owner = owner;
82 EXTRACT(status->caller_access); /* call ticket dependent */
83 EXTRACT(status->anon_access);
84 EXTRACT(status->mode);
85 bp++; /* parent.vnode */
86 bp++; /* parent.unique */
87 bp++; /* seg size */
88 status->mtime_client = ntohl(*bp++);
89 status->mtime_server = ntohl(*bp++);
90 group = make_kgid(&init_user_ns, ntohl(*bp++));
91 changed |= !gid_eq(group, status->group);
92 status->group = group;
93 bp++; /* sync counter */
94 data_version |= (u64) ntohl(*bp++) << 32;
95 EXTRACT(status->lock_count);
96 size |= (u64) ntohl(*bp++) << 32;
97 bp++; /* spare 4 */
98 *_bp = bp;
99 149
100 if (size != status->size) { 150 type = ntohl(xdr->type);
101 status->size = size; 151 abort_code = ntohl(xdr->abort_code);
102 changed |= true; 152 switch (type) {
153 case AFS_FTYPE_FILE:
154 case AFS_FTYPE_DIR:
155 case AFS_FTYPE_SYMLINK:
156 if (type != status->type &&
157 vnode &&
158 !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
159 pr_warning("Vnode %x:%x:%x changed type %u to %u\n",
160 vnode->fid.vid,
161 vnode->fid.vnode,
162 vnode->fid.unique,
163 status->type, type);
164 goto bad;
165 }
166 status->type = type;
167 break;
168 case AFS_FTYPE_INVALID:
169 if (abort_code != 0) {
170 status->abort_code = abort_code;
171 ret = 0;
172 goto out;
173 }
174 /* Fall through */
175 default:
176 goto bad;
103 } 177 }
104 status->mode &= S_IALLUGO;
105 178
106 _debug("vnode time %lx, %lx", 179#define EXTRACT_M(FIELD) \
107 status->mtime_client, status->mtime_server); 180 do { \
181 u32 x = ntohl(xdr->FIELD); \
182 if (status->FIELD != x) { \
183 flags |= AFS_VNODE_META_CHANGED; \
184 status->FIELD = x; \
185 } \
186 } while (0)
108 187
109 if (vnode) { 188 EXTRACT_M(nlink);
110 if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) { 189 EXTRACT_M(author);
111 _debug("vnode changed"); 190 EXTRACT_M(owner);
112 i_size_write(&vnode->vfs_inode, size); 191 EXTRACT_M(caller_access); /* call ticket dependent */
113 vnode->vfs_inode.i_uid = status->owner; 192 EXTRACT_M(anon_access);
114 vnode->vfs_inode.i_gid = status->group; 193 EXTRACT_M(mode);
115 vnode->vfs_inode.i_generation = vnode->fid.unique; 194 EXTRACT_M(group);
116 set_nlink(&vnode->vfs_inode, status->nlink); 195
117 196 status->mtime_client = ntohl(xdr->mtime_client);
118 mode = vnode->vfs_inode.i_mode; 197 status->mtime_server = ntohl(xdr->mtime_server);
119 mode &= ~S_IALLUGO; 198 status->lock_count = ntohl(xdr->lock_count);
120 mode |= status->mode; 199
121 barrier(); 200 size = (u64)ntohl(xdr->size_lo);
122 vnode->vfs_inode.i_mode = mode; 201 size |= (u64)ntohl(xdr->size_hi) << 32;
123 } 202 status->size = size;
203
204 data_version = (u64)ntohl(xdr->data_version_lo);
205 data_version |= (u64)ntohl(xdr->data_version_hi) << 32;
206 if (data_version != status->data_version) {
207 status->data_version = data_version;
208 flags |= AFS_VNODE_DATA_CHANGED;
209 }
124 210
125 vnode->vfs_inode.i_ctime.tv_sec = status->mtime_client; 211 if (read_req) {
126 vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime; 212 read_req->data_version = data_version;
127 vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime; 213 read_req->file_size = size;
128 inode_set_iversion_raw(&vnode->vfs_inode, data_version);
129 } 214 }
130 215
131 expected_version = status->data_version; 216 *_bp = (const void *)*_bp + sizeof(*xdr);
132 if (store_version)
133 expected_version = *store_version;
134 217
135 if (expected_version != data_version) { 218 if (vnode) {
136 status->data_version = data_version; 219 if (test_bit(AFS_VNODE_UNSET, &vnode->flags))
137 if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) { 220 flags |= AFS_VNODE_NOT_YET_SET;
138 _debug("vnode modified %llx on {%x:%u}", 221 afs_update_inode_from_status(vnode, status, expected_version,
139 (unsigned long long) data_version, 222 flags);
140 vnode->fid.vid, vnode->fid.vnode);
141 set_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags);
142 set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
143 }
144 } else if (store_version) {
145 status->data_version = data_version;
146 } 223 }
147 224
225 ret = 0;
226
227out:
148 if (vnode) 228 if (vnode)
149 write_sequnlock(&vnode->cb_lock); 229 write_sequnlock(&vnode->cb_lock);
230 return ret;
231
232bad:
233 xdr_dump_bad(*_bp);
234 ret = afs_protocol_error(call, -EBADMSG);
235 goto out;
150} 236}
151 237
152/* 238/*
@@ -274,7 +360,7 @@ static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
274/* 360/*
275 * deliver reply data to an FS.FetchStatus 361 * deliver reply data to an FS.FetchStatus
276 */ 362 */
277static int afs_deliver_fs_fetch_status(struct afs_call *call) 363static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)
278{ 364{
279 struct afs_vnode *vnode = call->reply[0]; 365 struct afs_vnode *vnode = call->reply[0];
280 const __be32 *bp; 366 const __be32 *bp;
@@ -288,7 +374,9 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
288 374
289 /* unmarshall the reply once we've received all of it */ 375 /* unmarshall the reply once we've received all of it */
290 bp = call->buffer; 376 bp = call->buffer;
291 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 377 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
378 &call->expected_version, NULL) < 0)
379 return afs_protocol_error(call, -EBADMSG);
292 xdr_decode_AFSCallBack(call, vnode, &bp); 380 xdr_decode_AFSCallBack(call, vnode, &bp);
293 if (call->reply[1]) 381 if (call->reply[1])
294 xdr_decode_AFSVolSync(&bp, call->reply[1]); 382 xdr_decode_AFSVolSync(&bp, call->reply[1]);
@@ -300,17 +388,18 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
300/* 388/*
301 * FS.FetchStatus operation type 389 * FS.FetchStatus operation type
302 */ 390 */
303static const struct afs_call_type afs_RXFSFetchStatus = { 391static const struct afs_call_type afs_RXFSFetchStatus_vnode = {
304 .name = "FS.FetchStatus", 392 .name = "FS.FetchStatus(vnode)",
305 .op = afs_FS_FetchStatus, 393 .op = afs_FS_FetchStatus,
306 .deliver = afs_deliver_fs_fetch_status, 394 .deliver = afs_deliver_fs_fetch_status_vnode,
307 .destructor = afs_flat_call_destructor, 395 .destructor = afs_flat_call_destructor,
308}; 396};
309 397
310/* 398/*
311 * fetch the status information for a file 399 * fetch the status information for a file
312 */ 400 */
313int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync) 401int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync,
402 bool new_inode)
314{ 403{
315 struct afs_vnode *vnode = fc->vnode; 404 struct afs_vnode *vnode = fc->vnode;
316 struct afs_call *call; 405 struct afs_call *call;
@@ -320,7 +409,8 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy
320 _enter(",%x,{%x:%u},,", 409 _enter(",%x,{%x:%u},,",
321 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 410 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
322 411
323 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4); 412 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus_vnode,
413 16, (21 + 3 + 6) * 4);
324 if (!call) { 414 if (!call) {
325 fc->ac.error = -ENOMEM; 415 fc->ac.error = -ENOMEM;
326 return -ENOMEM; 416 return -ENOMEM;
@@ -329,6 +419,7 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy
329 call->key = fc->key; 419 call->key = fc->key;
330 call->reply[0] = vnode; 420 call->reply[0] = vnode;
331 call->reply[1] = volsync; 421 call->reply[1] = volsync;
422 call->expected_version = new_inode ? 1 : vnode->status.data_version;
332 423
333 /* marshall the parameters */ 424 /* marshall the parameters */
334 bp = call->request; 425 bp = call->request;
@@ -464,7 +555,9 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
464 return ret; 555 return ret;
465 556
466 bp = call->buffer; 557 bp = call->buffer;
467 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 558 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
559 &vnode->status.data_version, req) < 0)
560 return afs_protocol_error(call, -EBADMSG);
468 xdr_decode_AFSCallBack(call, vnode, &bp); 561 xdr_decode_AFSCallBack(call, vnode, &bp);
469 if (call->reply[1]) 562 if (call->reply[1])
470 xdr_decode_AFSVolSync(&bp, call->reply[1]); 563 xdr_decode_AFSVolSync(&bp, call->reply[1]);
@@ -534,6 +627,7 @@ static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
534 call->reply[0] = vnode; 627 call->reply[0] = vnode;
535 call->reply[1] = NULL; /* volsync */ 628 call->reply[1] = NULL; /* volsync */
536 call->reply[2] = req; 629 call->reply[2] = req;
630 call->expected_version = vnode->status.data_version;
537 631
538 /* marshall the parameters */ 632 /* marshall the parameters */
539 bp = call->request; 633 bp = call->request;
@@ -546,7 +640,7 @@ static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
546 bp[6] = 0; 640 bp[6] = 0;
547 bp[7] = htonl(lower_32_bits(req->len)); 641 bp[7] = htonl(lower_32_bits(req->len));
548 642
549 atomic_inc(&req->usage); 643 refcount_inc(&req->usage);
550 call->cb_break = fc->cb_break; 644 call->cb_break = fc->cb_break;
551 afs_use_fs_server(call, fc->cbi); 645 afs_use_fs_server(call, fc->cbi);
552 trace_afs_make_fs_call(call, &vnode->fid); 646 trace_afs_make_fs_call(call, &vnode->fid);
@@ -578,6 +672,7 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
578 call->reply[0] = vnode; 672 call->reply[0] = vnode;
579 call->reply[1] = NULL; /* volsync */ 673 call->reply[1] = NULL; /* volsync */
580 call->reply[2] = req; 674 call->reply[2] = req;
675 call->expected_version = vnode->status.data_version;
581 676
582 /* marshall the parameters */ 677 /* marshall the parameters */
583 bp = call->request; 678 bp = call->request;
@@ -588,7 +683,7 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
588 bp[4] = htonl(lower_32_bits(req->pos)); 683 bp[4] = htonl(lower_32_bits(req->pos));
589 bp[5] = htonl(lower_32_bits(req->len)); 684 bp[5] = htonl(lower_32_bits(req->len));
590 685
591 atomic_inc(&req->usage); 686 refcount_inc(&req->usage);
592 call->cb_break = fc->cb_break; 687 call->cb_break = fc->cb_break;
593 afs_use_fs_server(call, fc->cbi); 688 afs_use_fs_server(call, fc->cbi);
594 trace_afs_make_fs_call(call, &vnode->fid); 689 trace_afs_make_fs_call(call, &vnode->fid);
@@ -613,8 +708,10 @@ static int afs_deliver_fs_create_vnode(struct afs_call *call)
613 /* unmarshall the reply once we've received all of it */ 708 /* unmarshall the reply once we've received all of it */
614 bp = call->buffer; 709 bp = call->buffer;
615 xdr_decode_AFSFid(&bp, call->reply[1]); 710 xdr_decode_AFSFid(&bp, call->reply[1]);
616 xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL); 711 if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 ||
617 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 712 xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
713 &call->expected_version, NULL) < 0)
714 return afs_protocol_error(call, -EBADMSG);
618 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]); 715 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]);
619 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 716 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
620 717
@@ -645,6 +742,7 @@ static const struct afs_call_type afs_RXFSMakeDir = {
645int afs_fs_create(struct afs_fs_cursor *fc, 742int afs_fs_create(struct afs_fs_cursor *fc,
646 const char *name, 743 const char *name,
647 umode_t mode, 744 umode_t mode,
745 u64 current_data_version,
648 struct afs_fid *newfid, 746 struct afs_fid *newfid,
649 struct afs_file_status *newstatus, 747 struct afs_file_status *newstatus,
650 struct afs_callback *newcb) 748 struct afs_callback *newcb)
@@ -672,6 +770,7 @@ int afs_fs_create(struct afs_fs_cursor *fc,
672 call->reply[1] = newfid; 770 call->reply[1] = newfid;
673 call->reply[2] = newstatus; 771 call->reply[2] = newstatus;
674 call->reply[3] = newcb; 772 call->reply[3] = newcb;
773 call->expected_version = current_data_version + 1;
675 774
676 /* marshall the parameters */ 775 /* marshall the parameters */
677 bp = call->request; 776 bp = call->request;
@@ -715,7 +814,9 @@ static int afs_deliver_fs_remove(struct afs_call *call)
715 814
716 /* unmarshall the reply once we've received all of it */ 815 /* unmarshall the reply once we've received all of it */
717 bp = call->buffer; 816 bp = call->buffer;
718 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 817 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
818 &call->expected_version, NULL) < 0)
819 return afs_protocol_error(call, -EBADMSG);
719 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 820 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
720 821
721 _leave(" = 0 [done]"); 822 _leave(" = 0 [done]");
@@ -742,7 +843,8 @@ static const struct afs_call_type afs_RXFSRemoveDir = {
742/* 843/*
743 * remove a file or directory 844 * remove a file or directory
744 */ 845 */
745int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir) 846int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
847 u64 current_data_version)
746{ 848{
747 struct afs_vnode *vnode = fc->vnode; 849 struct afs_vnode *vnode = fc->vnode;
748 struct afs_call *call; 850 struct afs_call *call;
@@ -764,6 +866,7 @@ int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir)
764 866
765 call->key = fc->key; 867 call->key = fc->key;
766 call->reply[0] = vnode; 868 call->reply[0] = vnode;
869 call->expected_version = current_data_version + 1;
767 870
768 /* marshall the parameters */ 871 /* marshall the parameters */
769 bp = call->request; 872 bp = call->request;
@@ -801,8 +904,10 @@ static int afs_deliver_fs_link(struct afs_call *call)
801 904
802 /* unmarshall the reply once we've received all of it */ 905 /* unmarshall the reply once we've received all of it */
803 bp = call->buffer; 906 bp = call->buffer;
804 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 907 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 ||
805 xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL); 908 xdr_decode_AFSFetchStatus(call, &bp, &dvnode->status, dvnode,
909 &call->expected_version, NULL) < 0)
910 return afs_protocol_error(call, -EBADMSG);
806 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 911 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
807 912
808 _leave(" = 0 [done]"); 913 _leave(" = 0 [done]");
@@ -823,7 +928,7 @@ static const struct afs_call_type afs_RXFSLink = {
823 * make a hard link 928 * make a hard link
824 */ 929 */
825int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 930int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
826 const char *name) 931 const char *name, u64 current_data_version)
827{ 932{
828 struct afs_vnode *dvnode = fc->vnode; 933 struct afs_vnode *dvnode = fc->vnode;
829 struct afs_call *call; 934 struct afs_call *call;
@@ -844,6 +949,7 @@ int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
844 call->key = fc->key; 949 call->key = fc->key;
845 call->reply[0] = dvnode; 950 call->reply[0] = dvnode;
846 call->reply[1] = vnode; 951 call->reply[1] = vnode;
952 call->expected_version = current_data_version + 1;
847 953
848 /* marshall the parameters */ 954 /* marshall the parameters */
849 bp = call->request; 955 bp = call->request;
@@ -885,8 +991,10 @@ static int afs_deliver_fs_symlink(struct afs_call *call)
885 /* unmarshall the reply once we've received all of it */ 991 /* unmarshall the reply once we've received all of it */
886 bp = call->buffer; 992 bp = call->buffer;
887 xdr_decode_AFSFid(&bp, call->reply[1]); 993 xdr_decode_AFSFid(&bp, call->reply[1]);
888 xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL); 994 if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) ||
889 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 995 xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
996 &call->expected_version, NULL) < 0)
997 return afs_protocol_error(call, -EBADMSG);
890 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 998 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
891 999
892 _leave(" = 0 [done]"); 1000 _leave(" = 0 [done]");
@@ -909,6 +1017,7 @@ static const struct afs_call_type afs_RXFSSymlink = {
909int afs_fs_symlink(struct afs_fs_cursor *fc, 1017int afs_fs_symlink(struct afs_fs_cursor *fc,
910 const char *name, 1018 const char *name,
911 const char *contents, 1019 const char *contents,
1020 u64 current_data_version,
912 struct afs_fid *newfid, 1021 struct afs_fid *newfid,
913 struct afs_file_status *newstatus) 1022 struct afs_file_status *newstatus)
914{ 1023{
@@ -937,6 +1046,7 @@ int afs_fs_symlink(struct afs_fs_cursor *fc,
937 call->reply[0] = vnode; 1046 call->reply[0] = vnode;
938 call->reply[1] = newfid; 1047 call->reply[1] = newfid;
939 call->reply[2] = newstatus; 1048 call->reply[2] = newstatus;
1049 call->expected_version = current_data_version + 1;
940 1050
941 /* marshall the parameters */ 1051 /* marshall the parameters */
942 bp = call->request; 1052 bp = call->request;
@@ -987,10 +1097,13 @@ static int afs_deliver_fs_rename(struct afs_call *call)
987 1097
988 /* unmarshall the reply once we've received all of it */ 1098 /* unmarshall the reply once we've received all of it */
989 bp = call->buffer; 1099 bp = call->buffer;
990 xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL); 1100 if (xdr_decode_AFSFetchStatus(call, &bp, &orig_dvnode->status, orig_dvnode,
991 if (new_dvnode != orig_dvnode) 1101 &call->expected_version, NULL) < 0)
992 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode, 1102 return afs_protocol_error(call, -EBADMSG);
993 NULL); 1103 if (new_dvnode != orig_dvnode &&
1104 xdr_decode_AFSFetchStatus(call, &bp, &new_dvnode->status, new_dvnode,
1105 &call->expected_version_2, NULL) < 0)
1106 return afs_protocol_error(call, -EBADMSG);
994 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1107 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
995 1108
996 _leave(" = 0 [done]"); 1109 _leave(" = 0 [done]");
@@ -1013,7 +1126,9 @@ static const struct afs_call_type afs_RXFSRename = {
1013int afs_fs_rename(struct afs_fs_cursor *fc, 1126int afs_fs_rename(struct afs_fs_cursor *fc,
1014 const char *orig_name, 1127 const char *orig_name,
1015 struct afs_vnode *new_dvnode, 1128 struct afs_vnode *new_dvnode,
1016 const char *new_name) 1129 const char *new_name,
1130 u64 current_orig_data_version,
1131 u64 current_new_data_version)
1017{ 1132{
1018 struct afs_vnode *orig_dvnode = fc->vnode; 1133 struct afs_vnode *orig_dvnode = fc->vnode;
1019 struct afs_call *call; 1134 struct afs_call *call;
@@ -1041,6 +1156,8 @@ int afs_fs_rename(struct afs_fs_cursor *fc,
1041 call->key = fc->key; 1156 call->key = fc->key;
1042 call->reply[0] = orig_dvnode; 1157 call->reply[0] = orig_dvnode;
1043 call->reply[1] = new_dvnode; 1158 call->reply[1] = new_dvnode;
1159 call->expected_version = current_orig_data_version + 1;
1160 call->expected_version_2 = current_new_data_version + 1;
1044 1161
1045 /* marshall the parameters */ 1162 /* marshall the parameters */
1046 bp = call->request; 1163 bp = call->request;
@@ -1089,8 +1206,9 @@ static int afs_deliver_fs_store_data(struct afs_call *call)
1089 1206
1090 /* unmarshall the reply once we've received all of it */ 1207 /* unmarshall the reply once we've received all of it */
1091 bp = call->buffer; 1208 bp = call->buffer;
1092 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, 1209 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
1093 &call->store_version); 1210 &call->expected_version, NULL) < 0)
1211 return afs_protocol_error(call, -EBADMSG);
1094 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1212 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1095 1213
1096 afs_pages_written_back(vnode, call); 1214 afs_pages_written_back(vnode, call);
@@ -1147,7 +1265,7 @@ static int afs_fs_store_data64(struct afs_fs_cursor *fc,
1147 call->first_offset = offset; 1265 call->first_offset = offset;
1148 call->last_to = to; 1266 call->last_to = to;
1149 call->send_pages = true; 1267 call->send_pages = true;
1150 call->store_version = vnode->status.data_version + 1; 1268 call->expected_version = vnode->status.data_version + 1;
1151 1269
1152 /* marshall the parameters */ 1270 /* marshall the parameters */
1153 bp = call->request; 1271 bp = call->request;
@@ -1222,7 +1340,7 @@ int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1222 call->first_offset = offset; 1340 call->first_offset = offset;
1223 call->last_to = to; 1341 call->last_to = to;
1224 call->send_pages = true; 1342 call->send_pages = true;
1225 call->store_version = vnode->status.data_version + 1; 1343 call->expected_version = vnode->status.data_version + 1;
1226 1344
1227 /* marshall the parameters */ 1345 /* marshall the parameters */
1228 bp = call->request; 1346 bp = call->request;
@@ -1252,7 +1370,6 @@ int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1252 */ 1370 */
1253static int afs_deliver_fs_store_status(struct afs_call *call) 1371static int afs_deliver_fs_store_status(struct afs_call *call)
1254{ 1372{
1255 afs_dataversion_t *store_version;
1256 struct afs_vnode *vnode = call->reply[0]; 1373 struct afs_vnode *vnode = call->reply[0];
1257 const __be32 *bp; 1374 const __be32 *bp;
1258 int ret; 1375 int ret;
@@ -1264,12 +1381,10 @@ static int afs_deliver_fs_store_status(struct afs_call *call)
1264 return ret; 1381 return ret;
1265 1382
1266 /* unmarshall the reply once we've received all of it */ 1383 /* unmarshall the reply once we've received all of it */
1267 store_version = NULL;
1268 if (call->operation_ID == FSSTOREDATA)
1269 store_version = &call->store_version;
1270
1271 bp = call->buffer; 1384 bp = call->buffer;
1272 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version); 1385 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
1386 &call->expected_version, NULL) < 0)
1387 return afs_protocol_error(call, -EBADMSG);
1273 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1388 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1274 1389
1275 _leave(" = 0 [done]"); 1390 _leave(" = 0 [done]");
@@ -1324,7 +1439,7 @@ static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr)
1324 1439
1325 call->key = fc->key; 1440 call->key = fc->key;
1326 call->reply[0] = vnode; 1441 call->reply[0] = vnode;
1327 call->store_version = vnode->status.data_version + 1; 1442 call->expected_version = vnode->status.data_version + 1;
1328 1443
1329 /* marshall the parameters */ 1444 /* marshall the parameters */
1330 bp = call->request; 1445 bp = call->request;
@@ -1373,7 +1488,7 @@ static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1373 1488
1374 call->key = fc->key; 1489 call->key = fc->key;
1375 call->reply[0] = vnode; 1490 call->reply[0] = vnode;
1376 call->store_version = vnode->status.data_version + 1; 1491 call->expected_version = vnode->status.data_version + 1;
1377 1492
1378 /* marshall the parameters */ 1493 /* marshall the parameters */
1379 bp = call->request; 1494 bp = call->request;
@@ -1418,6 +1533,7 @@ int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1418 1533
1419 call->key = fc->key; 1534 call->key = fc->key;
1420 call->reply[0] = vnode; 1535 call->reply[0] = vnode;
1536 call->expected_version = vnode->status.data_version;
1421 1537
1422 /* marshall the parameters */ 1538 /* marshall the parameters */
1423 bp = call->request; 1539 bp = call->request;
@@ -1471,7 +1587,7 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1471 call->count = ntohl(call->tmp); 1587 call->count = ntohl(call->tmp);
1472 _debug("volname length: %u", call->count); 1588 _debug("volname length: %u", call->count);
1473 if (call->count >= AFSNAMEMAX) 1589 if (call->count >= AFSNAMEMAX)
1474 return -EBADMSG; 1590 return afs_protocol_error(call, -EBADMSG);
1475 call->offset = 0; 1591 call->offset = 0;
1476 call->unmarshall++; 1592 call->unmarshall++;
1477 1593
@@ -1518,7 +1634,7 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1518 call->count = ntohl(call->tmp); 1634 call->count = ntohl(call->tmp);
1519 _debug("offline msg length: %u", call->count); 1635 _debug("offline msg length: %u", call->count);
1520 if (call->count >= AFSNAMEMAX) 1636 if (call->count >= AFSNAMEMAX)
1521 return -EBADMSG; 1637 return afs_protocol_error(call, -EBADMSG);
1522 call->offset = 0; 1638 call->offset = 0;
1523 call->unmarshall++; 1639 call->unmarshall++;
1524 1640
@@ -1565,7 +1681,7 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1565 call->count = ntohl(call->tmp); 1681 call->count = ntohl(call->tmp);
1566 _debug("motd length: %u", call->count); 1682 _debug("motd length: %u", call->count);
1567 if (call->count >= AFSNAMEMAX) 1683 if (call->count >= AFSNAMEMAX)
1568 return -EBADMSG; 1684 return afs_protocol_error(call, -EBADMSG);
1569 call->offset = 0; 1685 call->offset = 0;
1570 call->unmarshall++; 1686 call->unmarshall++;
1571 1687
@@ -1947,3 +2063,265 @@ int afs_fs_get_capabilities(struct afs_net *net,
1947 trace_afs_make_fs_call(call, NULL); 2063 trace_afs_make_fs_call(call, NULL);
1948 return afs_make_call(ac, call, GFP_NOFS, false); 2064 return afs_make_call(ac, call, GFP_NOFS, false);
1949} 2065}
2066
2067/*
2068 * Deliver reply data to an FS.FetchStatus with no vnode.
2069 */
2070static int afs_deliver_fs_fetch_status(struct afs_call *call)
2071{
2072 struct afs_file_status *status = call->reply[1];
2073 struct afs_callback *callback = call->reply[2];
2074 struct afs_volsync *volsync = call->reply[3];
2075 struct afs_vnode *vnode = call->reply[0];
2076 const __be32 *bp;
2077 int ret;
2078
2079 ret = afs_transfer_reply(call);
2080 if (ret < 0)
2081 return ret;
2082
2083 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
2084
2085 /* unmarshall the reply once we've received all of it */
2086 bp = call->buffer;
2087 xdr_decode_AFSFetchStatus(call, &bp, status, vnode,
2088 &call->expected_version, NULL);
2089 callback[call->count].version = ntohl(bp[0]);
2090 callback[call->count].expiry = ntohl(bp[1]);
2091 callback[call->count].type = ntohl(bp[2]);
2092 if (vnode)
2093 xdr_decode_AFSCallBack(call, vnode, &bp);
2094 else
2095 bp += 3;
2096 if (volsync)
2097 xdr_decode_AFSVolSync(&bp, volsync);
2098
2099 _leave(" = 0 [done]");
2100 return 0;
2101}
2102
2103/*
2104 * FS.FetchStatus operation type
2105 */
2106static const struct afs_call_type afs_RXFSFetchStatus = {
2107 .name = "FS.FetchStatus",
2108 .op = afs_FS_FetchStatus,
2109 .deliver = afs_deliver_fs_fetch_status,
2110 .destructor = afs_flat_call_destructor,
2111};
2112
2113/*
2114 * Fetch the status information for a fid without needing a vnode handle.
2115 */
2116int afs_fs_fetch_status(struct afs_fs_cursor *fc,
2117 struct afs_net *net,
2118 struct afs_fid *fid,
2119 struct afs_file_status *status,
2120 struct afs_callback *callback,
2121 struct afs_volsync *volsync)
2122{
2123 struct afs_call *call;
2124 __be32 *bp;
2125
2126 _enter(",%x,{%x:%u},,",
2127 key_serial(fc->key), fid->vid, fid->vnode);
2128
2129 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
2130 if (!call) {
2131 fc->ac.error = -ENOMEM;
2132 return -ENOMEM;
2133 }
2134
2135 call->key = fc->key;
2136 call->reply[0] = NULL; /* vnode for fid[0] */
2137 call->reply[1] = status;
2138 call->reply[2] = callback;
2139 call->reply[3] = volsync;
2140 call->expected_version = 1; /* vnode->status.data_version */
2141
2142 /* marshall the parameters */
2143 bp = call->request;
2144 bp[0] = htonl(FSFETCHSTATUS);
2145 bp[1] = htonl(fid->vid);
2146 bp[2] = htonl(fid->vnode);
2147 bp[3] = htonl(fid->unique);
2148
2149 call->cb_break = fc->cb_break;
2150 afs_use_fs_server(call, fc->cbi);
2151 trace_afs_make_fs_call(call, fid);
2152 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2153}
2154
2155/*
2156 * Deliver reply data to an FS.InlineBulkStatus call
2157 */
2158static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
2159{
2160 struct afs_file_status *statuses;
2161 struct afs_callback *callbacks;
2162 struct afs_vnode *vnode = call->reply[0];
2163 const __be32 *bp;
2164 u32 tmp;
2165 int ret;
2166
2167 _enter("{%u}", call->unmarshall);
2168
2169 switch (call->unmarshall) {
2170 case 0:
2171 call->offset = 0;
2172 call->unmarshall++;
2173
2174 /* Extract the file status count and array in two steps */
2175 case 1:
2176 _debug("extract status count");
2177 ret = afs_extract_data(call, &call->tmp, 4, true);
2178 if (ret < 0)
2179 return ret;
2180
2181 tmp = ntohl(call->tmp);
2182 _debug("status count: %u/%u", tmp, call->count2);
2183 if (tmp != call->count2)
2184 return afs_protocol_error(call, -EBADMSG);
2185
2186 call->count = 0;
2187 call->unmarshall++;
2188 more_counts:
2189 call->offset = 0;
2190
2191 case 2:
2192 _debug("extract status array %u", call->count);
2193 ret = afs_extract_data(call, call->buffer, 21 * 4, true);
2194 if (ret < 0)
2195 return ret;
2196
2197 bp = call->buffer;
2198 statuses = call->reply[1];
2199 if (xdr_decode_AFSFetchStatus(call, &bp, &statuses[call->count],
2200 call->count == 0 ? vnode : NULL,
2201 NULL, NULL) < 0)
2202 return afs_protocol_error(call, -EBADMSG);
2203
2204 call->count++;
2205 if (call->count < call->count2)
2206 goto more_counts;
2207
2208 call->count = 0;
2209 call->unmarshall++;
2210 call->offset = 0;
2211
2212 /* Extract the callback count and array in two steps */
2213 case 3:
2214 _debug("extract CB count");
2215 ret = afs_extract_data(call, &call->tmp, 4, true);
2216 if (ret < 0)
2217 return ret;
2218
2219 tmp = ntohl(call->tmp);
2220 _debug("CB count: %u", tmp);
2221 if (tmp != call->count2)
2222 return afs_protocol_error(call, -EBADMSG);
2223 call->count = 0;
2224 call->unmarshall++;
2225 more_cbs:
2226 call->offset = 0;
2227
2228 case 4:
2229 _debug("extract CB array");
2230 ret = afs_extract_data(call, call->buffer, 3 * 4, true);
2231 if (ret < 0)
2232 return ret;
2233
2234 _debug("unmarshall CB array");
2235 bp = call->buffer;
2236 callbacks = call->reply[2];
2237 callbacks[call->count].version = ntohl(bp[0]);
2238 callbacks[call->count].expiry = ntohl(bp[1]);
2239 callbacks[call->count].type = ntohl(bp[2]);
2240 statuses = call->reply[1];
2241 if (call->count == 0 && vnode && statuses[0].abort_code == 0)
2242 xdr_decode_AFSCallBack(call, vnode, &bp);
2243 call->count++;
2244 if (call->count < call->count2)
2245 goto more_cbs;
2246
2247 call->offset = 0;
2248 call->unmarshall++;
2249
2250 case 5:
2251 ret = afs_extract_data(call, call->buffer, 6 * 4, false);
2252 if (ret < 0)
2253 return ret;
2254
2255 bp = call->buffer;
2256 if (call->reply[3])
2257 xdr_decode_AFSVolSync(&bp, call->reply[3]);
2258
2259 call->offset = 0;
2260 call->unmarshall++;
2261
2262 case 6:
2263 break;
2264 }
2265
2266 _leave(" = 0 [done]");
2267 return 0;
2268}
2269
2270/*
2271 * FS.InlineBulkStatus operation type
2272 */
2273static const struct afs_call_type afs_RXFSInlineBulkStatus = {
2274 .name = "FS.InlineBulkStatus",
2275 .op = afs_FS_InlineBulkStatus,
2276 .deliver = afs_deliver_fs_inline_bulk_status,
2277 .destructor = afs_flat_call_destructor,
2278};
2279
2280/*
2281 * Fetch the status information for up to 50 files
2282 */
2283int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2284 struct afs_net *net,
2285 struct afs_fid *fids,
2286 struct afs_file_status *statuses,
2287 struct afs_callback *callbacks,
2288 unsigned int nr_fids,
2289 struct afs_volsync *volsync)
2290{
2291 struct afs_call *call;
2292 __be32 *bp;
2293 int i;
2294
2295 _enter(",%x,{%x:%u},%u",
2296 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2297
2298 call = afs_alloc_flat_call(net, &afs_RXFSInlineBulkStatus,
2299 (2 + nr_fids * 3) * 4,
2300 21 * 4);
2301 if (!call) {
2302 fc->ac.error = -ENOMEM;
2303 return -ENOMEM;
2304 }
2305
2306 call->key = fc->key;
2307 call->reply[0] = NULL; /* vnode for fid[0] */
2308 call->reply[1] = statuses;
2309 call->reply[2] = callbacks;
2310 call->reply[3] = volsync;
2311 call->count2 = nr_fids;
2312
2313 /* marshall the parameters */
2314 bp = call->request;
2315 *bp++ = htonl(FSINLINEBULKSTATUS);
2316 *bp++ = htonl(nr_fids);
2317 for (i = 0; i < nr_fids; i++) {
2318 *bp++ = htonl(fids[i].vid);
2319 *bp++ = htonl(fids[i].vnode);
2320 *bp++ = htonl(fids[i].unique);
2321 }
2322
2323 call->cb_break = fc->cb_break;
2324 afs_use_fs_server(call, fc->cbi);
2325 trace_afs_make_fs_call(call, &fids[0]);
2326 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2327}
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 65c5b1edd338..06194cfe9724 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -30,12 +30,11 @@ static const struct inode_operations afs_symlink_inode_operations = {
30}; 30};
31 31
32/* 32/*
33 * map the AFS file status to the inode member variables 33 * Initialise an inode from the vnode status.
34 */ 34 */
35static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) 35static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key)
36{ 36{
37 struct inode *inode = AFS_VNODE_TO_I(vnode); 37 struct inode *inode = AFS_VNODE_TO_I(vnode);
38 bool changed;
39 38
40 _debug("FS: ft=%d lk=%d sz=%llu ver=%Lu mod=%hu", 39 _debug("FS: ft=%d lk=%d sz=%llu ver=%Lu mod=%hu",
41 vnode->status.type, 40 vnode->status.type,
@@ -46,16 +45,21 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key)
46 45
47 read_seqlock_excl(&vnode->cb_lock); 46 read_seqlock_excl(&vnode->cb_lock);
48 47
48 afs_update_inode_from_status(vnode, &vnode->status, NULL,
49 AFS_VNODE_NOT_YET_SET);
50
49 switch (vnode->status.type) { 51 switch (vnode->status.type) {
50 case AFS_FTYPE_FILE: 52 case AFS_FTYPE_FILE:
51 inode->i_mode = S_IFREG | vnode->status.mode; 53 inode->i_mode = S_IFREG | vnode->status.mode;
52 inode->i_op = &afs_file_inode_operations; 54 inode->i_op = &afs_file_inode_operations;
53 inode->i_fop = &afs_file_operations; 55 inode->i_fop = &afs_file_operations;
56 inode->i_mapping->a_ops = &afs_fs_aops;
54 break; 57 break;
55 case AFS_FTYPE_DIR: 58 case AFS_FTYPE_DIR:
56 inode->i_mode = S_IFDIR | vnode->status.mode; 59 inode->i_mode = S_IFDIR | vnode->status.mode;
57 inode->i_op = &afs_dir_inode_operations; 60 inode->i_op = &afs_dir_inode_operations;
58 inode->i_fop = &afs_dir_file_operations; 61 inode->i_fop = &afs_dir_file_operations;
62 inode->i_mapping->a_ops = &afs_dir_aops;
59 break; 63 break;
60 case AFS_FTYPE_SYMLINK: 64 case AFS_FTYPE_SYMLINK:
61 /* Symlinks with a mode of 0644 are actually mountpoints. */ 65 /* Symlinks with a mode of 0644 are actually mountpoints. */
@@ -67,45 +71,31 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key)
67 inode->i_mode = S_IFDIR | 0555; 71 inode->i_mode = S_IFDIR | 0555;
68 inode->i_op = &afs_mntpt_inode_operations; 72 inode->i_op = &afs_mntpt_inode_operations;
69 inode->i_fop = &afs_mntpt_file_operations; 73 inode->i_fop = &afs_mntpt_file_operations;
74 inode->i_mapping->a_ops = &afs_fs_aops;
70 } else { 75 } else {
71 inode->i_mode = S_IFLNK | vnode->status.mode; 76 inode->i_mode = S_IFLNK | vnode->status.mode;
72 inode->i_op = &afs_symlink_inode_operations; 77 inode->i_op = &afs_symlink_inode_operations;
78 inode->i_mapping->a_ops = &afs_fs_aops;
73 } 79 }
74 inode_nohighmem(inode); 80 inode_nohighmem(inode);
75 break; 81 break;
76 default: 82 default:
77 printk("kAFS: AFS vnode with undefined type\n"); 83 printk("kAFS: AFS vnode with undefined type\n");
78 read_sequnlock_excl(&vnode->cb_lock); 84 read_sequnlock_excl(&vnode->cb_lock);
79 return -EBADMSG; 85 return afs_protocol_error(NULL, -EBADMSG);
80 } 86 }
81 87
82 changed = (vnode->status.size != inode->i_size);
83
84 set_nlink(inode, vnode->status.nlink);
85 inode->i_uid = vnode->status.owner;
86 inode->i_gid = vnode->status.group;
87 inode->i_size = vnode->status.size;
88 inode->i_ctime.tv_sec = vnode->status.mtime_client;
89 inode->i_ctime.tv_nsec = 0;
90 inode->i_atime = inode->i_mtime = inode->i_ctime;
91 inode->i_blocks = 0; 88 inode->i_blocks = 0;
92 inode->i_generation = vnode->fid.unique; 89 vnode->invalid_before = vnode->status.data_version;
93 inode_set_iversion_raw(inode, vnode->status.data_version);
94 inode->i_mapping->a_ops = &afs_fs_aops;
95 90
96 read_sequnlock_excl(&vnode->cb_lock); 91 read_sequnlock_excl(&vnode->cb_lock);
97
98#ifdef CONFIG_AFS_FSCACHE
99 if (changed)
100 fscache_attr_changed(vnode->cache);
101#endif
102 return 0; 92 return 0;
103} 93}
104 94
105/* 95/*
106 * Fetch file status from the volume. 96 * Fetch file status from the volume.
107 */ 97 */
108int afs_fetch_status(struct afs_vnode *vnode, struct key *key) 98int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool new_inode)
109{ 99{
110 struct afs_fs_cursor fc; 100 struct afs_fs_cursor fc;
111 int ret; 101 int ret;
@@ -119,7 +109,7 @@ int afs_fetch_status(struct afs_vnode *vnode, struct key *key)
119 if (afs_begin_vnode_operation(&fc, vnode, key)) { 109 if (afs_begin_vnode_operation(&fc, vnode, key)) {
120 while (afs_select_fileserver(&fc)) { 110 while (afs_select_fileserver(&fc)) {
121 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 111 fc.cb_break = vnode->cb_break + vnode->cb_s_break;
122 afs_fs_fetch_file_status(&fc, NULL); 112 afs_fs_fetch_file_status(&fc, NULL, new_inode);
123 } 113 }
124 114
125 afs_check_for_remote_deletion(&fc, fc.vnode); 115 afs_check_for_remote_deletion(&fc, fc.vnode);
@@ -255,6 +245,11 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
255 } __packed key; 245 } __packed key;
256 struct afs_vnode_cache_aux aux; 246 struct afs_vnode_cache_aux aux;
257 247
248 if (vnode->status.type == AFS_FTYPE_DIR) {
249 vnode->cache = NULL;
250 return;
251 }
252
258 key.vnode_id = vnode->fid.vnode; 253 key.vnode_id = vnode->fid.vnode;
259 key.unique = vnode->fid.unique; 254 key.unique = vnode->fid.unique;
260 key.vnode_id_ext[0] = 0; 255 key.vnode_id_ext[0] = 0;
@@ -307,7 +302,7 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
307 302
308 if (!status) { 303 if (!status) {
309 /* it's a remotely extant inode */ 304 /* it's a remotely extant inode */
310 ret = afs_fetch_status(vnode, key); 305 ret = afs_fetch_status(vnode, key, true);
311 if (ret < 0) 306 if (ret < 0)
312 goto bad_inode; 307 goto bad_inode;
313 } else { 308 } else {
@@ -331,15 +326,12 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
331 vnode->cb_expires_at += ktime_get_real_seconds(); 326 vnode->cb_expires_at += ktime_get_real_seconds();
332 } 327 }
333 328
334 /* set up caching before mapping the status, as map-status reads the 329 ret = afs_inode_init_from_status(vnode, key);
335 * first page of symlinks to see if they're really mountpoints */
336 inode->i_size = vnode->status.size;
337 afs_get_inode_cache(vnode);
338
339 ret = afs_inode_map_status(vnode, key);
340 if (ret < 0) 330 if (ret < 0)
341 goto bad_inode; 331 goto bad_inode;
342 332
333 afs_get_inode_cache(vnode);
334
343 /* success */ 335 /* success */
344 clear_bit(AFS_VNODE_UNSET, &vnode->flags); 336 clear_bit(AFS_VNODE_UNSET, &vnode->flags);
345 inode->i_flags |= S_NOATIME; 337 inode->i_flags |= S_NOATIME;
@@ -349,10 +341,6 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
349 341
350 /* failure */ 342 /* failure */
351bad_inode: 343bad_inode:
352#ifdef CONFIG_AFS_FSCACHE
353 fscache_relinquish_cookie(vnode->cache, NULL, ret == -ENOENT);
354 vnode->cache = NULL;
355#endif
356 iget_failed(inode); 344 iget_failed(inode);
357 _leave(" = %d [bad]", ret); 345 _leave(" = %d [bad]", ret);
358 return ERR_PTR(ret); 346 return ERR_PTR(ret);
@@ -407,8 +395,11 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
407 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { 395 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
408 if (vnode->cb_s_break != vnode->cb_interest->server->cb_s_break) { 396 if (vnode->cb_s_break != vnode->cb_interest->server->cb_s_break) {
409 vnode->cb_s_break = vnode->cb_interest->server->cb_s_break; 397 vnode->cb_s_break = vnode->cb_interest->server->cb_s_break;
410 } else if (!test_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags) && 398 } else if (vnode->status.type == AFS_FTYPE_DIR &&
411 !test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) && 399 test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) &&
400 vnode->cb_expires_at - 10 > now) {
401 valid = true;
402 } else if (!test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) &&
412 vnode->cb_expires_at - 10 > now) { 403 vnode->cb_expires_at - 10 > now) {
413 valid = true; 404 valid = true;
414 } 405 }
@@ -432,7 +423,7 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
432 * access */ 423 * access */
433 if (!test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { 424 if (!test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
434 _debug("not promised"); 425 _debug("not promised");
435 ret = afs_fetch_status(vnode, key); 426 ret = afs_fetch_status(vnode, key, false);
436 if (ret < 0) { 427 if (ret < 0) {
437 if (ret == -ENOENT) { 428 if (ret == -ENOENT) {
438 set_bit(AFS_VNODE_DELETED, &vnode->flags); 429 set_bit(AFS_VNODE_DELETED, &vnode->flags);
@@ -453,8 +444,6 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
453 * different */ 444 * different */
454 if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) 445 if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags))
455 afs_zap_data(vnode); 446 afs_zap_data(vnode);
456
457 clear_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags);
458 mutex_unlock(&vnode->validate_lock); 447 mutex_unlock(&vnode->validate_lock);
459valid: 448valid:
460 _leave(" = 0"); 449 _leave(" = 0");
@@ -544,7 +533,7 @@ void afs_evict_inode(struct inode *inode)
544 } 533 }
545#endif 534#endif
546 535
547 afs_put_permits(vnode->permit_cache); 536 afs_put_permits(rcu_access_pointer(vnode->permit_cache));
548 _leave(""); 537 _leave("");
549} 538}
550 539
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index a6a1d75eee41..f8086ec95e24 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -122,7 +122,8 @@ struct afs_call {
122 u32 operation_ID; /* operation ID for an incoming call */ 122 u32 operation_ID; /* operation ID for an incoming call */
123 u32 count; /* count for use in unmarshalling */ 123 u32 count; /* count for use in unmarshalling */
124 __be32 tmp; /* place to extract temporary data */ 124 __be32 tmp; /* place to extract temporary data */
125 afs_dataversion_t store_version; /* updated version expected from store */ 125 afs_dataversion_t expected_version; /* Updated version expected from store */
126 afs_dataversion_t expected_version_2; /* 2nd updated version expected from store */
126}; 127};
127 128
128struct afs_call_type { 129struct afs_call_type {
@@ -173,11 +174,14 @@ struct afs_read {
173 loff_t len; /* How much we're asking for */ 174 loff_t len; /* How much we're asking for */
174 loff_t actual_len; /* How much we're actually getting */ 175 loff_t actual_len; /* How much we're actually getting */
175 loff_t remain; /* Amount remaining */ 176 loff_t remain; /* Amount remaining */
176 atomic_t usage; 177 loff_t file_size; /* File size returned by server */
178 afs_dataversion_t data_version; /* Version number returned by server */
179 refcount_t usage;
177 unsigned int index; /* Which page we're reading into */ 180 unsigned int index; /* Which page we're reading into */
178 unsigned int nr_pages; 181 unsigned int nr_pages;
179 void (*page_done)(struct afs_call *, struct afs_read *); 182 void (*page_done)(struct afs_call *, struct afs_read *);
180 struct page *pages[]; 183 struct page **pages;
184 struct page *array[];
181}; 185};
182 186
183/* 187/*
@@ -199,6 +203,18 @@ static inline struct afs_super_info *AFS_FS_S(struct super_block *sb)
199extern struct file_system_type afs_fs_type; 203extern struct file_system_type afs_fs_type;
200 204
201/* 205/*
206 * Set of substitutes for @sys.
207 */
208struct afs_sysnames {
209#define AFS_NR_SYSNAME 16
210 char *subs[AFS_NR_SYSNAME];
211 refcount_t usage;
212 unsigned short nr;
213 short error;
214 char blank[1];
215};
216
217/*
202 * AFS network namespace record. 218 * AFS network namespace record.
203 */ 219 */
204struct afs_net { 220struct afs_net {
@@ -245,9 +261,25 @@ struct afs_net {
245 struct mutex lock_manager_mutex; 261 struct mutex lock_manager_mutex;
246 262
247 /* Misc */ 263 /* Misc */
248 struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */ 264 struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */
265 struct afs_sysnames *sysnames;
266 rwlock_t sysnames_lock;
267
268 /* Statistics counters */
269 atomic_t n_lookup; /* Number of lookups done */
270 atomic_t n_reval; /* Number of dentries needing revalidation */
271 atomic_t n_inval; /* Number of invalidations by the server */
272 atomic_t n_relpg; /* Number of invalidations by releasepage */
273 atomic_t n_read_dir; /* Number of directory pages read */
274 atomic_t n_dir_cr; /* Number of directory entry creation edits */
275 atomic_t n_dir_rm; /* Number of directory entry removal edits */
276 atomic_t n_stores; /* Number of store ops */
277 atomic_long_t n_store_bytes; /* Number of bytes stored */
278 atomic_long_t n_fetch_bytes; /* Number of bytes fetched */
279 atomic_t n_fetches; /* Number of data fetch ops */
249}; 280};
250 281
282extern const char afs_init_sysname[];
251extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns 283extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns
252 284
253enum afs_cell_state { 285enum afs_cell_state {
@@ -363,6 +395,7 @@ struct afs_server {
363#define AFS_SERVER_FL_UPDATING 4 395#define AFS_SERVER_FL_UPDATING 4
364#define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */ 396#define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */
365#define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */ 397#define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */
398#define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */
366 atomic_t usage; 399 atomic_t usage;
367 u32 addr_version; /* Address list version */ 400 u32 addr_version; /* Address list version */
368 401
@@ -455,10 +488,11 @@ struct afs_vnode {
455 struct afs_volume *volume; /* volume on which vnode resides */ 488 struct afs_volume *volume; /* volume on which vnode resides */
456 struct afs_fid fid; /* the file identifier for this inode */ 489 struct afs_fid fid; /* the file identifier for this inode */
457 struct afs_file_status status; /* AFS status info for this file */ 490 struct afs_file_status status; /* AFS status info for this file */
491 afs_dataversion_t invalid_before; /* Child dentries are invalid before this */
458#ifdef CONFIG_AFS_FSCACHE 492#ifdef CONFIG_AFS_FSCACHE
459 struct fscache_cookie *cache; /* caching cookie */ 493 struct fscache_cookie *cache; /* caching cookie */
460#endif 494#endif
461 struct afs_permits *permit_cache; /* cache of permits so far obtained */ 495 struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */
462 struct mutex io_lock; /* Lock for serialising I/O on this mutex */ 496 struct mutex io_lock; /* Lock for serialising I/O on this mutex */
463 struct mutex validate_lock; /* lock for validating this vnode */ 497 struct mutex validate_lock; /* lock for validating this vnode */
464 spinlock_t wb_lock; /* lock for wb_keys */ 498 spinlock_t wb_lock; /* lock for wb_keys */
@@ -466,12 +500,13 @@ struct afs_vnode {
466 unsigned long flags; 500 unsigned long flags;
467#define AFS_VNODE_CB_PROMISED 0 /* Set if vnode has a callback promise */ 501#define AFS_VNODE_CB_PROMISED 0 /* Set if vnode has a callback promise */
468#define AFS_VNODE_UNSET 1 /* set if vnode attributes not yet set */ 502#define AFS_VNODE_UNSET 1 /* set if vnode attributes not yet set */
469#define AFS_VNODE_DIR_MODIFIED 2 /* set if dir vnode's data modified */ 503#define AFS_VNODE_DIR_VALID 2 /* Set if dir contents are valid */
470#define AFS_VNODE_ZAP_DATA 3 /* set if vnode's data should be invalidated */ 504#define AFS_VNODE_ZAP_DATA 3 /* set if vnode's data should be invalidated */
471#define AFS_VNODE_DELETED 4 /* set if vnode deleted on server */ 505#define AFS_VNODE_DELETED 4 /* set if vnode deleted on server */
472#define AFS_VNODE_MOUNTPOINT 5 /* set if vnode is a mountpoint symlink */ 506#define AFS_VNODE_MOUNTPOINT 5 /* set if vnode is a mountpoint symlink */
473#define AFS_VNODE_AUTOCELL 6 /* set if Vnode is an auto mount point */ 507#define AFS_VNODE_AUTOCELL 6 /* set if Vnode is an auto mount point */
474#define AFS_VNODE_PSEUDODIR 7 /* set if Vnode is a pseudo directory */ 508#define AFS_VNODE_PSEUDODIR 7 /* set if Vnode is a pseudo directory */
509#define AFS_VNODE_NEW_CONTENT 8 /* Set if file has new content (create/trunc-0) */
475 510
476 struct list_head wb_keys; /* List of keys available for writeback */ 511 struct list_head wb_keys; /* List of keys available for writeback */
477 struct list_head pending_locks; /* locks waiting to be granted */ 512 struct list_head pending_locks; /* locks waiting to be granted */
@@ -611,7 +646,7 @@ extern struct fscache_cookie_def afs_vnode_cache_index_def;
611 */ 646 */
612extern void afs_init_callback_state(struct afs_server *); 647extern void afs_init_callback_state(struct afs_server *);
613extern void afs_break_callback(struct afs_vnode *); 648extern void afs_break_callback(struct afs_vnode *);
614extern void afs_break_callbacks(struct afs_server *, size_t,struct afs_callback[]); 649extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*);
615 650
616extern int afs_register_server_cb_interest(struct afs_vnode *, struct afs_server_entry *); 651extern int afs_register_server_cb_interest(struct afs_vnode *, struct afs_server_entry *);
617extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *); 652extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *);
@@ -646,11 +681,26 @@ extern bool afs_cm_incoming_call(struct afs_call *);
646 */ 681 */
647extern const struct file_operations afs_dir_file_operations; 682extern const struct file_operations afs_dir_file_operations;
648extern const struct inode_operations afs_dir_inode_operations; 683extern const struct inode_operations afs_dir_inode_operations;
684extern const struct address_space_operations afs_dir_aops;
685extern const struct dentry_operations afs_fs_dentry_operations;
686
687extern void afs_d_release(struct dentry *);
688
689/*
690 * dir_edit.c
691 */
692extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *,
693 enum afs_edit_dir_reason);
694extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason);
695
696/*
697 * dynroot.c
698 */
649extern const struct file_operations afs_dynroot_file_operations; 699extern const struct file_operations afs_dynroot_file_operations;
650extern const struct inode_operations afs_dynroot_inode_operations; 700extern const struct inode_operations afs_dynroot_inode_operations;
651extern const struct dentry_operations afs_fs_dentry_operations; 701extern const struct dentry_operations afs_dynroot_dentry_operations;
652 702
653extern bool afs_dir_check_page(struct inode *, struct page *); 703extern struct inode *afs_try_auto_mntpt(struct dentry *, struct inode *);
654 704
655/* 705/*
656 * file.c 706 * file.c
@@ -680,17 +730,23 @@ extern int afs_flock(struct file *, int, struct file_lock *);
680/* 730/*
681 * fsclient.c 731 * fsclient.c
682 */ 732 */
683extern int afs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_volsync *); 733#define AFS_VNODE_NOT_YET_SET 0x01
734#define AFS_VNODE_META_CHANGED 0x02
735#define AFS_VNODE_DATA_CHANGED 0x04
736extern void afs_update_inode_from_status(struct afs_vnode *, struct afs_file_status *,
737 const afs_dataversion_t *, u8);
738
739extern int afs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_volsync *, bool);
684extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *); 740extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *);
685extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct afs_read *); 741extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct afs_read *);
686extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t, 742extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t, u64,
687 struct afs_fid *, struct afs_file_status *, struct afs_callback *); 743 struct afs_fid *, struct afs_file_status *, struct afs_callback *);
688extern int afs_fs_remove(struct afs_fs_cursor *, const char *, bool); 744extern int afs_fs_remove(struct afs_fs_cursor *, const char *, bool, u64);
689extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *); 745extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64);
690extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, 746extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, u64,
691 struct afs_fid *, struct afs_file_status *); 747 struct afs_fid *, struct afs_file_status *);
692extern int afs_fs_rename(struct afs_fs_cursor *, const char *, 748extern int afs_fs_rename(struct afs_fs_cursor *, const char *,
693 struct afs_vnode *, const char *); 749 struct afs_vnode *, const char *, u64, u64);
694extern int afs_fs_store_data(struct afs_fs_cursor *, struct address_space *, 750extern int afs_fs_store_data(struct afs_fs_cursor *, struct address_space *,
695 pgoff_t, pgoff_t, unsigned, unsigned); 751 pgoff_t, pgoff_t, unsigned, unsigned);
696extern int afs_fs_setattr(struct afs_fs_cursor *, struct iattr *); 752extern int afs_fs_setattr(struct afs_fs_cursor *, struct iattr *);
@@ -702,11 +758,18 @@ extern int afs_fs_give_up_all_callbacks(struct afs_net *, struct afs_server *,
702 struct afs_addr_cursor *, struct key *); 758 struct afs_addr_cursor *, struct key *);
703extern int afs_fs_get_capabilities(struct afs_net *, struct afs_server *, 759extern int afs_fs_get_capabilities(struct afs_net *, struct afs_server *,
704 struct afs_addr_cursor *, struct key *); 760 struct afs_addr_cursor *, struct key *);
761extern int afs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *,
762 struct afs_fid *, struct afs_file_status *,
763 struct afs_callback *, unsigned int,
764 struct afs_volsync *);
765extern int afs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *,
766 struct afs_fid *, struct afs_file_status *,
767 struct afs_callback *, struct afs_volsync *);
705 768
706/* 769/*
707 * inode.c 770 * inode.c
708 */ 771 */
709extern int afs_fetch_status(struct afs_vnode *, struct key *); 772extern int afs_fetch_status(struct afs_vnode *, struct key *, bool);
710extern int afs_iget5_test(struct inode *, void *); 773extern int afs_iget5_test(struct inode *, void *);
711extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool); 774extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool);
712extern struct inode *afs_iget(struct super_block *, struct key *, 775extern struct inode *afs_iget(struct super_block *, struct key *,
@@ -754,6 +817,13 @@ static inline void afs_put_net(struct afs_net *net)
754{ 817{
755} 818}
756 819
820static inline void __afs_stat(atomic_t *s)
821{
822 atomic_inc(s);
823}
824
825#define afs_stat_v(vnode, n) __afs_stat(&afs_v2net(vnode)->n)
826
757/* 827/*
758 * misc.c 828 * misc.c
759 */ 829 */
@@ -781,6 +851,7 @@ extern int __net_init afs_proc_init(struct afs_net *);
781extern void __net_exit afs_proc_cleanup(struct afs_net *); 851extern void __net_exit afs_proc_cleanup(struct afs_net *);
782extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *); 852extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *);
783extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *); 853extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *);
854extern void afs_put_sysnames(struct afs_sysnames *);
784 855
785/* 856/*
786 * rotate.c 857 * rotate.c
@@ -809,6 +880,7 @@ extern void afs_flat_call_destructor(struct afs_call *);
809extern void afs_send_empty_reply(struct afs_call *); 880extern void afs_send_empty_reply(struct afs_call *);
810extern void afs_send_simple_reply(struct afs_call *, const void *, size_t); 881extern void afs_send_simple_reply(struct afs_call *, const void *, size_t);
811extern int afs_extract_data(struct afs_call *, void *, size_t, bool); 882extern int afs_extract_data(struct afs_call *, void *, size_t, bool);
883extern int afs_protocol_error(struct afs_call *, int);
812 884
813static inline int afs_transfer_reply(struct afs_call *call) 885static inline int afs_transfer_reply(struct afs_call *call)
814{ 886{
@@ -955,7 +1027,6 @@ extern int afs_writepage(struct page *, struct writeback_control *);
955extern int afs_writepages(struct address_space *, struct writeback_control *); 1027extern int afs_writepages(struct address_space *, struct writeback_control *);
956extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); 1028extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *);
957extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *); 1029extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *);
958extern int afs_flush(struct file *, fl_owner_t);
959extern int afs_fsync(struct file *, loff_t, loff_t, int); 1030extern int afs_fsync(struct file *, loff_t, loff_t, int);
960extern int afs_page_mkwrite(struct vm_fault *); 1031extern int afs_page_mkwrite(struct vm_fault *);
961extern void afs_prune_wb_keys(struct afs_vnode *); 1032extern void afs_prune_wb_keys(struct afs_vnode *);
diff --git a/fs/afs/main.c b/fs/afs/main.c
index 15a02a05ff40..d7560168b3bf 100644
--- a/fs/afs/main.c
+++ b/fs/afs/main.c
@@ -34,11 +34,42 @@ MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
34struct workqueue_struct *afs_wq; 34struct workqueue_struct *afs_wq;
35struct afs_net __afs_net; 35struct afs_net __afs_net;
36 36
37#if defined(CONFIG_ALPHA)
38const char afs_init_sysname[] = "alpha_linux26";
39#elif defined(CONFIG_X86_64)
40const char afs_init_sysname[] = "amd64_linux26";
41#elif defined(CONFIG_ARM)
42const char afs_init_sysname[] = "arm_linux26";
43#elif defined(CONFIG_ARM64)
44const char afs_init_sysname[] = "aarch64_linux26";
45#elif defined(CONFIG_X86_32)
46const char afs_init_sysname[] = "i386_linux26";
47#elif defined(CONFIG_IA64)
48const char afs_init_sysname[] = "ia64_linux26";
49#elif defined(CONFIG_PPC64)
50const char afs_init_sysname[] = "ppc64_linux26";
51#elif defined(CONFIG_PPC32)
52const char afs_init_sysname[] = "ppc_linux26";
53#elif defined(CONFIG_S390)
54#ifdef CONFIG_64BIT
55const char afs_init_sysname[] = "s390x_linux26";
56#else
57const char afs_init_sysname[] = "s390_linux26";
58#endif
59#elif defined(CONFIG_SPARC64)
60const char afs_init_sysname[] = "sparc64_linux26";
61#elif defined(CONFIG_SPARC32)
62const char afs_init_sysname[] = "sparc_linux26";
63#else
64const char afs_init_sysname[] = "unknown_linux26";
65#endif
66
37/* 67/*
38 * Initialise an AFS network namespace record. 68 * Initialise an AFS network namespace record.
39 */ 69 */
40static int __net_init afs_net_init(struct afs_net *net) 70static int __net_init afs_net_init(struct afs_net *net)
41{ 71{
72 struct afs_sysnames *sysnames;
42 int ret; 73 int ret;
43 74
44 net->live = true; 75 net->live = true;
@@ -67,6 +98,16 @@ static int __net_init afs_net_init(struct afs_net *net)
67 INIT_WORK(&net->fs_manager, afs_manage_servers); 98 INIT_WORK(&net->fs_manager, afs_manage_servers);
68 timer_setup(&net->fs_timer, afs_servers_timer, 0); 99 timer_setup(&net->fs_timer, afs_servers_timer, 0);
69 100
101 ret = -ENOMEM;
102 sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL);
103 if (!sysnames)
104 goto error_sysnames;
105 sysnames->subs[0] = (char *)&afs_init_sysname;
106 sysnames->nr = 1;
107 refcount_set(&sysnames->usage, 1);
108 net->sysnames = sysnames;
109 rwlock_init(&net->sysnames_lock);
110
70 /* Register the /proc stuff */ 111 /* Register the /proc stuff */
71 ret = afs_proc_init(net); 112 ret = afs_proc_init(net);
72 if (ret < 0) 113 if (ret < 0)
@@ -92,6 +133,8 @@ error_cell_init:
92 net->live = false; 133 net->live = false;
93 afs_proc_cleanup(net); 134 afs_proc_cleanup(net);
94error_proc: 135error_proc:
136 afs_put_sysnames(net->sysnames);
137error_sysnames:
95 net->live = false; 138 net->live = false;
96 return ret; 139 return ret;
97} 140}
@@ -106,6 +149,7 @@ static void __net_exit afs_net_exit(struct afs_net *net)
106 afs_purge_servers(net); 149 afs_purge_servers(net);
107 afs_close_socket(net); 150 afs_close_socket(net);
108 afs_proc_cleanup(net); 151 afs_proc_cleanup(net);
152 afs_put_sysnames(net->sysnames);
109} 153}
110 154
111/* 155/*
diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 4508dd54f789..839a22280606 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -126,6 +126,34 @@ static const struct file_operations afs_proc_servers_fops = {
126 .release = seq_release, 126 .release = seq_release,
127}; 127};
128 128
129static int afs_proc_sysname_open(struct inode *inode, struct file *file);
130static int afs_proc_sysname_release(struct inode *inode, struct file *file);
131static void *afs_proc_sysname_start(struct seq_file *p, loff_t *pos);
132static void *afs_proc_sysname_next(struct seq_file *p, void *v,
133 loff_t *pos);
134static void afs_proc_sysname_stop(struct seq_file *p, void *v);
135static int afs_proc_sysname_show(struct seq_file *m, void *v);
136static ssize_t afs_proc_sysname_write(struct file *file,
137 const char __user *buf,
138 size_t size, loff_t *_pos);
139
140static const struct seq_operations afs_proc_sysname_ops = {
141 .start = afs_proc_sysname_start,
142 .next = afs_proc_sysname_next,
143 .stop = afs_proc_sysname_stop,
144 .show = afs_proc_sysname_show,
145};
146
147static const struct file_operations afs_proc_sysname_fops = {
148 .open = afs_proc_sysname_open,
149 .read = seq_read,
150 .llseek = seq_lseek,
151 .release = afs_proc_sysname_release,
152 .write = afs_proc_sysname_write,
153};
154
155static const struct file_operations afs_proc_stats_fops;
156
129/* 157/*
130 * initialise the /proc/fs/afs/ directory 158 * initialise the /proc/fs/afs/ directory
131 */ 159 */
@@ -139,7 +167,9 @@ int afs_proc_init(struct afs_net *net)
139 167
140 if (!proc_create("cells", 0644, net->proc_afs, &afs_proc_cells_fops) || 168 if (!proc_create("cells", 0644, net->proc_afs, &afs_proc_cells_fops) ||
141 !proc_create("rootcell", 0644, net->proc_afs, &afs_proc_rootcell_fops) || 169 !proc_create("rootcell", 0644, net->proc_afs, &afs_proc_rootcell_fops) ||
142 !proc_create("servers", 0644, net->proc_afs, &afs_proc_servers_fops)) 170 !proc_create("servers", 0644, net->proc_afs, &afs_proc_servers_fops) ||
171 !proc_create("stats", 0644, net->proc_afs, &afs_proc_stats_fops) ||
172 !proc_create("sysname", 0644, net->proc_afs, &afs_proc_sysname_fops))
143 goto error_tree; 173 goto error_tree;
144 174
145 _leave(" = 0"); 175 _leave(" = 0");
@@ -183,6 +213,7 @@ static int afs_proc_cells_open(struct inode *inode, struct file *file)
183 * first item 213 * first item
184 */ 214 */
185static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos) 215static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos)
216 __acquires(rcu)
186{ 217{
187 struct afs_net *net = afs_seq2net(m); 218 struct afs_net *net = afs_seq2net(m);
188 219
@@ -204,6 +235,7 @@ static void *afs_proc_cells_next(struct seq_file *m, void *v, loff_t *pos)
204 * clean up after reading from the cells list 235 * clean up after reading from the cells list
205 */ 236 */
206static void afs_proc_cells_stop(struct seq_file *m, void *v) 237static void afs_proc_cells_stop(struct seq_file *m, void *v)
238 __releases(rcu)
207{ 239{
208 rcu_read_unlock(); 240 rcu_read_unlock();
209} 241}
@@ -282,7 +314,8 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
282 goto done; 314 goto done;
283 } 315 }
284 316
285 set_bit(AFS_CELL_FL_NO_GC, &cell->flags); 317 if (test_and_set_bit(AFS_CELL_FL_NO_GC, &cell->flags))
318 afs_put_cell(net, cell);
286 printk("kAFS: Added new cell '%s'\n", name); 319 printk("kAFS: Added new cell '%s'\n", name);
287 } else { 320 } else {
288 goto inval; 321 goto inval;
@@ -304,7 +337,40 @@ inval:
304static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, 337static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf,
305 size_t size, loff_t *_pos) 338 size_t size, loff_t *_pos)
306{ 339{
307 return 0; 340 struct afs_cell *cell;
341 struct afs_net *net = afs_proc2net(file);
342 unsigned int seq = 0;
343 char name[AFS_MAXCELLNAME + 1];
344 int len;
345
346 if (*_pos > 0)
347 return 0;
348 if (!net->ws_cell)
349 return 0;
350
351 rcu_read_lock();
352 do {
353 read_seqbegin_or_lock(&net->cells_lock, &seq);
354 len = 0;
355 cell = rcu_dereference_raw(net->ws_cell);
356 if (cell) {
357 len = cell->name_len;
358 memcpy(name, cell->name, len);
359 }
360 } while (need_seqretry(&net->cells_lock, seq));
361 done_seqretry(&net->cells_lock, seq);
362 rcu_read_unlock();
363
364 if (!len)
365 return 0;
366
367 name[len++] = '\n';
368 if (len > size)
369 len = size;
370 if (copy_to_user(buf, name, len) != 0)
371 return -EFAULT;
372 *_pos = 1;
373 return len;
308} 374}
309 375
310/* 376/*
@@ -327,6 +393,12 @@ static ssize_t afs_proc_rootcell_write(struct file *file,
327 if (IS_ERR(kbuf)) 393 if (IS_ERR(kbuf))
328 return PTR_ERR(kbuf); 394 return PTR_ERR(kbuf);
329 395
396 ret = -EINVAL;
397 if (kbuf[0] == '.')
398 goto out;
399 if (memchr(kbuf, '/', size))
400 goto out;
401
330 /* trim to first NL */ 402 /* trim to first NL */
331 s = memchr(kbuf, '\n', size); 403 s = memchr(kbuf, '\n', size);
332 if (s) 404 if (s)
@@ -339,6 +411,7 @@ static ssize_t afs_proc_rootcell_write(struct file *file,
339 if (ret >= 0) 411 if (ret >= 0)
340 ret = size; /* consume everything, always */ 412 ret = size; /* consume everything, always */
341 413
414out:
342 kfree(kbuf); 415 kfree(kbuf);
343 _leave(" = %d", ret); 416 _leave(" = %d", ret);
344 return ret; 417 return ret;
@@ -413,6 +486,7 @@ static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file)
413 * first item 486 * first item
414 */ 487 */
415static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos) 488static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos)
489 __acquires(cell->proc_lock)
416{ 490{
417 struct afs_cell *cell = m->private; 491 struct afs_cell *cell = m->private;
418 492
@@ -438,6 +512,7 @@ static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v,
438 * clean up after reading from the cells list 512 * clean up after reading from the cells list
439 */ 513 */
440static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v) 514static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v)
515 __releases(cell->proc_lock)
441{ 516{
442 struct afs_cell *cell = p->private; 517 struct afs_cell *cell = p->private;
443 518
@@ -500,6 +575,7 @@ static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file)
500 * first item 575 * first item
501 */ 576 */
502static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) 577static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos)
578 __acquires(rcu)
503{ 579{
504 struct afs_addr_list *alist; 580 struct afs_addr_list *alist;
505 struct afs_cell *cell = m->private; 581 struct afs_cell *cell = m->private;
@@ -544,6 +620,7 @@ static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v,
544 * clean up after reading from the cells list 620 * clean up after reading from the cells list
545 */ 621 */
546static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v) 622static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v)
623 __releases(rcu)
547{ 624{
548 rcu_read_unlock(); 625 rcu_read_unlock();
549} 626}
@@ -580,6 +657,7 @@ static int afs_proc_servers_open(struct inode *inode, struct file *file)
580 * first item. 657 * first item.
581 */ 658 */
582static void *afs_proc_servers_start(struct seq_file *m, loff_t *_pos) 659static void *afs_proc_servers_start(struct seq_file *m, loff_t *_pos)
660 __acquires(rcu)
583{ 661{
584 struct afs_net *net = afs_seq2net(m); 662 struct afs_net *net = afs_seq2net(m);
585 663
@@ -601,6 +679,7 @@ static void *afs_proc_servers_next(struct seq_file *m, void *v, loff_t *_pos)
601 * clean up after reading from the cells list 679 * clean up after reading from the cells list
602 */ 680 */
603static void afs_proc_servers_stop(struct seq_file *p, void *v) 681static void afs_proc_servers_stop(struct seq_file *p, void *v)
682 __releases(rcu)
604{ 683{
605 rcu_read_unlock(); 684 rcu_read_unlock();
606} 685}
@@ -626,3 +705,244 @@ static int afs_proc_servers_show(struct seq_file *m, void *v)
626 &alist->addrs[alist->index].transport); 705 &alist->addrs[alist->index].transport);
627 return 0; 706 return 0;
628} 707}
708
709void afs_put_sysnames(struct afs_sysnames *sysnames)
710{
711 int i;
712
713 if (sysnames && refcount_dec_and_test(&sysnames->usage)) {
714 for (i = 0; i < sysnames->nr; i++)
715 if (sysnames->subs[i] != afs_init_sysname &&
716 sysnames->subs[i] != sysnames->blank)
717 kfree(sysnames->subs[i]);
718 }
719}
720
721/*
722 * Handle opening of /proc/fs/afs/sysname. If it is opened for writing, we
723 * assume the caller wants to change the substitution list and we allocate a
724 * buffer to hold the list.
725 */
726static int afs_proc_sysname_open(struct inode *inode, struct file *file)
727{
728 struct afs_sysnames *sysnames;
729 struct seq_file *m;
730 int ret;
731
732 ret = seq_open(file, &afs_proc_sysname_ops);
733 if (ret < 0)
734 return ret;
735
736 if (file->f_mode & FMODE_WRITE) {
737 sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL);
738 if (!sysnames) {
739 seq_release(inode, file);
740 return -ENOMEM;
741 }
742
743 refcount_set(&sysnames->usage, 1);
744 m = file->private_data;
745 m->private = sysnames;
746 }
747
748 return 0;
749}
750
751/*
752 * Handle writes to /proc/fs/afs/sysname to set the @sys substitution.
753 */
754static ssize_t afs_proc_sysname_write(struct file *file,
755 const char __user *buf,
756 size_t size, loff_t *_pos)
757{
758 struct afs_sysnames *sysnames;
759 struct seq_file *m = file->private_data;
760 char *kbuf = NULL, *s, *p, *sub;
761 int ret, len;
762
763 sysnames = m->private;
764 if (!sysnames)
765 return -EINVAL;
766 if (sysnames->error)
767 return sysnames->error;
768
769 if (size >= PAGE_SIZE - 1) {
770 sysnames->error = -EINVAL;
771 return -EINVAL;
772 }
773 if (size == 0)
774 return 0;
775
776 kbuf = memdup_user_nul(buf, size);
777 if (IS_ERR(kbuf))
778 return PTR_ERR(kbuf);
779
780 inode_lock(file_inode(file));
781
782 p = kbuf;
783 while ((s = strsep(&p, " \t\n"))) {
784 len = strlen(s);
785 if (len == 0)
786 continue;
787 ret = -ENAMETOOLONG;
788 if (len >= AFSNAMEMAX)
789 goto error;
790
791 if (len >= 4 &&
792 s[len - 4] == '@' &&
793 s[len - 3] == 's' &&
794 s[len - 2] == 'y' &&
795 s[len - 1] == 's')
796 /* Protect against recursion */
797 goto invalid;
798
799 if (s[0] == '.' &&
800 (len < 2 || (len == 2 && s[1] == '.')))
801 goto invalid;
802
803 if (memchr(s, '/', len))
804 goto invalid;
805
806 ret = -EFBIG;
807 if (sysnames->nr >= AFS_NR_SYSNAME)
808 goto out;
809
810 if (strcmp(s, afs_init_sysname) == 0) {
811 sub = (char *)afs_init_sysname;
812 } else {
813 ret = -ENOMEM;
814 sub = kmemdup(s, len + 1, GFP_KERNEL);
815 if (!sub)
816 goto out;
817 }
818
819 sysnames->subs[sysnames->nr] = sub;
820 sysnames->nr++;
821 }
822
823 ret = size; /* consume everything, always */
824out:
825 inode_unlock(file_inode(file));
826 kfree(kbuf);
827 return ret;
828
829invalid:
830 ret = -EINVAL;
831error:
832 sysnames->error = ret;
833 goto out;
834}
835
836static int afs_proc_sysname_release(struct inode *inode, struct file *file)
837{
838 struct afs_sysnames *sysnames, *kill = NULL;
839 struct seq_file *m = file->private_data;
840 struct afs_net *net = afs_seq2net(m);
841
842 sysnames = m->private;
843 if (sysnames) {
844 if (!sysnames->error) {
845 kill = sysnames;
846 if (sysnames->nr == 0) {
847 sysnames->subs[0] = sysnames->blank;
848 sysnames->nr++;
849 }
850 write_lock(&net->sysnames_lock);
851 kill = net->sysnames;
852 net->sysnames = sysnames;
853 write_unlock(&net->sysnames_lock);
854 }
855 afs_put_sysnames(kill);
856 }
857
858 return seq_release(inode, file);
859}
860
861static void *afs_proc_sysname_start(struct seq_file *m, loff_t *pos)
862 __acquires(&net->sysnames_lock)
863{
864 struct afs_net *net = afs_seq2net(m);
865 struct afs_sysnames *names = net->sysnames;
866
867 read_lock(&net->sysnames_lock);
868
869 if (*pos >= names->nr)
870 return NULL;
871 return (void *)(unsigned long)(*pos + 1);
872}
873
874static void *afs_proc_sysname_next(struct seq_file *m, void *v, loff_t *pos)
875{
876 struct afs_net *net = afs_seq2net(m);
877 struct afs_sysnames *names = net->sysnames;
878
879 *pos += 1;
880 if (*pos >= names->nr)
881 return NULL;
882 return (void *)(unsigned long)(*pos + 1);
883}
884
885static void afs_proc_sysname_stop(struct seq_file *m, void *v)
886 __releases(&net->sysnames_lock)
887{
888 struct afs_net *net = afs_seq2net(m);
889
890 read_unlock(&net->sysnames_lock);
891}
892
893static int afs_proc_sysname_show(struct seq_file *m, void *v)
894{
895 struct afs_net *net = afs_seq2net(m);
896 struct afs_sysnames *sysnames = net->sysnames;
897 unsigned int i = (unsigned long)v - 1;
898
899 if (i < sysnames->nr)
900 seq_printf(m, "%s\n", sysnames->subs[i]);
901 return 0;
902}
903
904/*
905 * Display general per-net namespace statistics
906 */
907static int afs_proc_stats_show(struct seq_file *m, void *v)
908{
909 struct afs_net *net = afs_seq2net(m);
910
911 seq_puts(m, "kAFS statistics\n");
912
913 seq_printf(m, "dir-mgmt: look=%u reval=%u inval=%u relpg=%u\n",
914 atomic_read(&net->n_lookup),
915 atomic_read(&net->n_reval),
916 atomic_read(&net->n_inval),
917 atomic_read(&net->n_relpg));
918
919 seq_printf(m, "dir-data: rdpg=%u\n",
920 atomic_read(&net->n_read_dir));
921
922 seq_printf(m, "dir-edit: cr=%u rm=%u\n",
923 atomic_read(&net->n_dir_cr),
924 atomic_read(&net->n_dir_rm));
925
926 seq_printf(m, "file-rd : n=%u nb=%lu\n",
927 atomic_read(&net->n_fetches),
928 atomic_long_read(&net->n_fetch_bytes));
929 seq_printf(m, "file-wr : n=%u nb=%lu\n",
930 atomic_read(&net->n_stores),
931 atomic_long_read(&net->n_store_bytes));
932 return 0;
933}
934
935/*
936 * Open "/proc/fs/afs/stats" to allow reading of the stat counters.
937 */
938static int afs_proc_stats_open(struct inode *inode, struct file *file)
939{
940 return single_open(file, afs_proc_stats_show, NULL);
941}
942
943static const struct file_operations afs_proc_stats_fops = {
944 .open = afs_proc_stats_open,
945 .read = seq_read,
946 .llseek = seq_lseek,
947 .release = single_release,
948};
diff --git a/fs/afs/rotate.c b/fs/afs/rotate.c
index ad1328d85526..ac0feac9d746 100644
--- a/fs/afs/rotate.c
+++ b/fs/afs/rotate.c
@@ -21,7 +21,7 @@
21/* 21/*
22 * Initialise a filesystem server cursor for iterating over FS servers. 22 * Initialise a filesystem server cursor for iterating over FS servers.
23 */ 23 */
24void afs_init_fs_cursor(struct afs_fs_cursor *fc, struct afs_vnode *vnode) 24static void afs_init_fs_cursor(struct afs_fs_cursor *fc, struct afs_vnode *vnode)
25{ 25{
26 memset(fc, 0, sizeof(*fc)); 26 memset(fc, 0, sizeof(*fc));
27} 27}
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index f7ae54b6a393..5c6263972ec9 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -926,3 +926,12 @@ int afs_extract_data(struct afs_call *call, void *buf, size_t count,
926 afs_set_call_complete(call, ret, remote_abort); 926 afs_set_call_complete(call, ret, remote_abort);
927 return ret; 927 return ret;
928} 928}
929
930/*
931 * Log protocol error production.
932 */
933noinline int afs_protocol_error(struct afs_call *call, int error)
934{
935 trace_afs_protocol_error(call, error, __builtin_return_address(0));
936 return error;
937}
diff --git a/fs/afs/security.c b/fs/afs/security.c
index b88b7d45fdaa..cea2fff313dc 100644
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -178,18 +178,14 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key,
178 } 178 }
179 } 179 }
180 180
181 if (cb_break != (vnode->cb_break + vnode->cb_interest->server->cb_s_break)) { 181 if (cb_break != (vnode->cb_break + vnode->cb_interest->server->cb_s_break))
182 rcu_read_unlock();
183 goto someone_else_changed_it; 182 goto someone_else_changed_it;
184 }
185 183
186 /* We need a ref on any permits list we want to copy as we'll have to 184 /* We need a ref on any permits list we want to copy as we'll have to
187 * drop the lock to do memory allocation. 185 * drop the lock to do memory allocation.
188 */ 186 */
189 if (permits && !refcount_inc_not_zero(&permits->usage)) { 187 if (permits && !refcount_inc_not_zero(&permits->usage))
190 rcu_read_unlock();
191 goto someone_else_changed_it; 188 goto someone_else_changed_it;
192 }
193 189
194 rcu_read_unlock(); 190 rcu_read_unlock();
195 191
@@ -278,6 +274,7 @@ someone_else_changed_it:
278 /* Someone else changed the cache under us - don't recheck at this 274 /* Someone else changed the cache under us - don't recheck at this
279 * time. 275 * time.
280 */ 276 */
277 rcu_read_unlock();
281 return; 278 return;
282} 279}
283 280
@@ -296,8 +293,6 @@ int afs_check_permit(struct afs_vnode *vnode, struct key *key,
296 _enter("{%x:%u},%x", 293 _enter("{%x:%u},%x",
297 vnode->fid.vid, vnode->fid.vnode, key_serial(key)); 294 vnode->fid.vid, vnode->fid.vnode, key_serial(key));
298 295
299 permits = vnode->permit_cache;
300
301 /* check the permits to see if we've got one yet */ 296 /* check the permits to see if we've got one yet */
302 if (key == vnode->volume->cell->anonymous_key) { 297 if (key == vnode->volume->cell->anonymous_key) {
303 _debug("anon"); 298 _debug("anon");
@@ -327,7 +322,7 @@ int afs_check_permit(struct afs_vnode *vnode, struct key *key,
327 */ 322 */
328 _debug("no valid permit"); 323 _debug("no valid permit");
329 324
330 ret = afs_fetch_status(vnode, key); 325 ret = afs_fetch_status(vnode, key, false);
331 if (ret < 0) { 326 if (ret < 0) {
332 *_access = 0; 327 *_access = 0;
333 _leave(" = %d", ret); 328 _leave(" = %d", ret);
diff --git a/fs/afs/server.c b/fs/afs/server.c
index a43ef77dabae..e23be63998a8 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -59,7 +59,8 @@ struct afs_server *afs_find_server(struct afs_net *net,
59 alist = rcu_dereference(server->addresses); 59 alist = rcu_dereference(server->addresses);
60 for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) { 60 for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) {
61 b = &alist->addrs[i].transport.sin6; 61 b = &alist->addrs[i].transport.sin6;
62 diff = (u16)a->sin6_port - (u16)b->sin6_port; 62 diff = ((u16 __force)a->sin6_port -
63 (u16 __force)b->sin6_port);
63 if (diff == 0) 64 if (diff == 0)
64 diff = memcmp(&a->sin6_addr, 65 diff = memcmp(&a->sin6_addr,
65 &b->sin6_addr, 66 &b->sin6_addr,
@@ -79,10 +80,11 @@ struct afs_server *afs_find_server(struct afs_net *net,
79 alist = rcu_dereference(server->addresses); 80 alist = rcu_dereference(server->addresses);
80 for (i = 0; i < alist->nr_ipv4; i++) { 81 for (i = 0; i < alist->nr_ipv4; i++) {
81 b = &alist->addrs[i].transport.sin6; 82 b = &alist->addrs[i].transport.sin6;
82 diff = (u16)a->sin6_port - (u16)b->sin6_port; 83 diff = ((u16 __force)a->sin6_port -
84 (u16 __force)b->sin6_port);
83 if (diff == 0) 85 if (diff == 0)
84 diff = ((u32)a->sin6_addr.s6_addr32[3] - 86 diff = ((u32 __force)a->sin6_addr.s6_addr32[3] -
85 (u32)b->sin6_addr.s6_addr32[3]); 87 (u32 __force)b->sin6_addr.s6_addr32[3]);
86 if (diff == 0) 88 if (diff == 0)
87 goto found; 89 goto found;
88 if (diff < 0) { 90 if (diff < 0) {
@@ -381,7 +383,7 @@ static void afs_server_rcu(struct rcu_head *rcu)
381{ 383{
382 struct afs_server *server = container_of(rcu, struct afs_server, rcu); 384 struct afs_server *server = container_of(rcu, struct afs_server, rcu);
383 385
384 afs_put_addrlist(server->addresses); 386 afs_put_addrlist(rcu_access_pointer(server->addresses));
385 kfree(server); 387 kfree(server);
386} 388}
387 389
@@ -390,7 +392,7 @@ static void afs_server_rcu(struct rcu_head *rcu)
390 */ 392 */
391static void afs_destroy_server(struct afs_net *net, struct afs_server *server) 393static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
392{ 394{
393 struct afs_addr_list *alist = server->addresses; 395 struct afs_addr_list *alist = rcu_access_pointer(server->addresses);
394 struct afs_addr_cursor ac = { 396 struct afs_addr_cursor ac = {
395 .alist = alist, 397 .alist = alist,
396 .addr = &alist->addrs[0], 398 .addr = &alist->addrs[0],
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 3623c952b6ff..65081ec3c36e 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -154,7 +154,7 @@ static int afs_show_devname(struct seq_file *m, struct dentry *root)
154 seq_puts(m, "none"); 154 seq_puts(m, "none");
155 return 0; 155 return 0;
156 } 156 }
157 157
158 switch (volume->type) { 158 switch (volume->type) {
159 case AFSVL_RWVOL: 159 case AFSVL_RWVOL:
160 break; 160 break;
@@ -269,7 +269,7 @@ static int afs_parse_device_name(struct afs_mount_params *params,
269 int cellnamesz; 269 int cellnamesz;
270 270
271 _enter(",%s", name); 271 _enter(",%s", name);
272 272
273 if (!name) { 273 if (!name) {
274 printk(KERN_ERR "kAFS: no volume name specified\n"); 274 printk(KERN_ERR "kAFS: no volume name specified\n");
275 return -EINVAL; 275 return -EINVAL;
@@ -418,7 +418,10 @@ static int afs_fill_super(struct super_block *sb,
418 if (!sb->s_root) 418 if (!sb->s_root)
419 goto error; 419 goto error;
420 420
421 sb->s_d_op = &afs_fs_dentry_operations; 421 if (params->dyn_root)
422 sb->s_d_op = &afs_dynroot_dentry_operations;
423 else
424 sb->s_d_op = &afs_fs_dentry_operations;
422 425
423 _leave(" = 0"); 426 _leave(" = 0");
424 return 0; 427 return 0;
@@ -676,7 +679,7 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf)
676 buf->f_bfree = 0; 679 buf->f_bfree = 0;
677 return 0; 680 return 0;
678 } 681 }
679 682
680 key = afs_request_key(vnode->volume->cell); 683 key = afs_request_key(vnode->volume->cell);
681 if (IS_ERR(key)) 684 if (IS_ERR(key))
682 return PTR_ERR(key); 685 return PTR_ERR(key);
diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c
index 5d8562f1ad4a..1ed7e2fd2f35 100644
--- a/fs/afs/vlclient.c
+++ b/fs/afs/vlclient.c
@@ -303,7 +303,7 @@ struct afs_addr_list *afs_vl_get_addrs_u(struct afs_net *net,
303 r->uuid.clock_seq_hi_and_reserved = htonl(u->clock_seq_hi_and_reserved); 303 r->uuid.clock_seq_hi_and_reserved = htonl(u->clock_seq_hi_and_reserved);
304 r->uuid.clock_seq_low = htonl(u->clock_seq_low); 304 r->uuid.clock_seq_low = htonl(u->clock_seq_low);
305 for (i = 0; i < 6; i++) 305 for (i = 0; i < 6; i++)
306 r->uuid.node[i] = ntohl(u->node[i]); 306 r->uuid.node[i] = htonl(u->node[i]);
307 307
308 trace_afs_make_vl_call(call); 308 trace_afs_make_vl_call(call);
309 return (struct afs_addr_list *)afs_make_call(ac, call, GFP_KERNEL, false); 309 return (struct afs_addr_list *)afs_make_call(ac, call, GFP_KERNEL, false);
@@ -450,7 +450,7 @@ again:
450 call->count2 = ntohl(*bp); /* Type or next count */ 450 call->count2 = ntohl(*bp); /* Type or next count */
451 451
452 if (call->count > YFS_MAXENDPOINTS) 452 if (call->count > YFS_MAXENDPOINTS)
453 return -EBADMSG; 453 return afs_protocol_error(call, -EBADMSG);
454 454
455 alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT); 455 alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT);
456 if (!alist) 456 if (!alist)
@@ -474,7 +474,7 @@ again:
474 size = sizeof(__be32) * (1 + 4 + 1); 474 size = sizeof(__be32) * (1 + 4 + 1);
475 break; 475 break;
476 default: 476 default:
477 return -EBADMSG; 477 return afs_protocol_error(call, -EBADMSG);
478 } 478 }
479 479
480 size += sizeof(__be32); 480 size += sizeof(__be32);
@@ -487,24 +487,24 @@ again:
487 switch (call->count2) { 487 switch (call->count2) {
488 case YFS_ENDPOINT_IPV4: 488 case YFS_ENDPOINT_IPV4:
489 if (ntohl(bp[0]) != sizeof(__be32) * 2) 489 if (ntohl(bp[0]) != sizeof(__be32) * 2)
490 return -EBADMSG; 490 return afs_protocol_error(call, -EBADMSG);
491 afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2])); 491 afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2]));
492 bp += 3; 492 bp += 3;
493 break; 493 break;
494 case YFS_ENDPOINT_IPV6: 494 case YFS_ENDPOINT_IPV6:
495 if (ntohl(bp[0]) != sizeof(__be32) * 5) 495 if (ntohl(bp[0]) != sizeof(__be32) * 5)
496 return -EBADMSG; 496 return afs_protocol_error(call, -EBADMSG);
497 afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5])); 497 afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5]));
498 bp += 6; 498 bp += 6;
499 break; 499 break;
500 default: 500 default:
501 return -EBADMSG; 501 return afs_protocol_error(call, -EBADMSG);
502 } 502 }
503 503
504 /* Got either the type of the next entry or the count of 504 /* Got either the type of the next entry or the count of
505 * volEndpoints if no more fsEndpoints. 505 * volEndpoints if no more fsEndpoints.
506 */ 506 */
507 call->count2 = htonl(*bp++); 507 call->count2 = ntohl(*bp++);
508 508
509 call->offset = 0; 509 call->offset = 0;
510 call->count--; 510 call->count--;
@@ -517,7 +517,7 @@ again:
517 if (!call->count) 517 if (!call->count)
518 goto end; 518 goto end;
519 if (call->count > YFS_MAXENDPOINTS) 519 if (call->count > YFS_MAXENDPOINTS)
520 return -EBADMSG; 520 return afs_protocol_error(call, -EBADMSG);
521 521
522 call->unmarshall = 3; 522 call->unmarshall = 3;
523 523
@@ -531,7 +531,7 @@ again:
531 return ret; 531 return ret;
532 532
533 bp = call->buffer; 533 bp = call->buffer;
534 call->count2 = htonl(*bp++); 534 call->count2 = ntohl(*bp++);
535 call->offset = 0; 535 call->offset = 0;
536 call->unmarshall = 4; 536 call->unmarshall = 4;
537 537
@@ -545,7 +545,7 @@ again:
545 size = sizeof(__be32) * (1 + 4 + 1); 545 size = sizeof(__be32) * (1 + 4 + 1);
546 break; 546 break;
547 default: 547 default:
548 return -EBADMSG; 548 return afs_protocol_error(call, -EBADMSG);
549 } 549 }
550 550
551 if (call->count > 1) 551 if (call->count > 1)
@@ -558,16 +558,16 @@ again:
558 switch (call->count2) { 558 switch (call->count2) {
559 case YFS_ENDPOINT_IPV4: 559 case YFS_ENDPOINT_IPV4:
560 if (ntohl(bp[0]) != sizeof(__be32) * 2) 560 if (ntohl(bp[0]) != sizeof(__be32) * 2)
561 return -EBADMSG; 561 return afs_protocol_error(call, -EBADMSG);
562 bp += 3; 562 bp += 3;
563 break; 563 break;
564 case YFS_ENDPOINT_IPV6: 564 case YFS_ENDPOINT_IPV6:
565 if (ntohl(bp[0]) != sizeof(__be32) * 5) 565 if (ntohl(bp[0]) != sizeof(__be32) * 5)
566 return -EBADMSG; 566 return afs_protocol_error(call, -EBADMSG);
567 bp += 6; 567 bp += 6;
568 break; 568 break;
569 default: 569 default:
570 return -EBADMSG; 570 return afs_protocol_error(call, -EBADMSG);
571 } 571 }
572 572
573 /* Got either the type of the next entry or the count of 573 /* Got either the type of the next entry or the count of
@@ -576,7 +576,7 @@ again:
576 call->offset = 0; 576 call->offset = 0;
577 call->count--; 577 call->count--;
578 if (call->count > 0) { 578 if (call->count > 0) {
579 call->count2 = htonl(*bp++); 579 call->count2 = ntohl(*bp++);
580 goto again; 580 goto again;
581 } 581 }
582 582
diff --git a/fs/afs/write.c b/fs/afs/write.c
index dbc3c0b0142d..c164698dc304 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -42,10 +42,11 @@ static int afs_fill_page(struct afs_vnode *vnode, struct key *key,
42 if (!req) 42 if (!req)
43 return -ENOMEM; 43 return -ENOMEM;
44 44
45 atomic_set(&req->usage, 1); 45 refcount_set(&req->usage, 1);
46 req->pos = pos; 46 req->pos = pos;
47 req->len = len; 47 req->len = len;
48 req->nr_pages = 1; 48 req->nr_pages = 1;
49 req->pages = req->array;
49 req->pages[0] = page; 50 req->pages[0] = page;
50 get_page(page); 51 get_page(page);
51 52
@@ -124,7 +125,12 @@ try_again:
124 page->index, priv); 125 page->index, priv);
125 goto flush_conflicting_write; 126 goto flush_conflicting_write;
126 } 127 }
127 if (to < f || from > t) 128 /* If the file is being filled locally, allow inter-write
129 * spaces to be merged into writes. If it's not, only write
130 * back what the user gives us.
131 */
132 if (!test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags) &&
133 (to < f || from > t))
128 goto flush_conflicting_write; 134 goto flush_conflicting_write;
129 if (from < f) 135 if (from < f)
130 f = from; 136 f = from;
@@ -355,6 +361,12 @@ found_key:
355 } 361 }
356 362
357 switch (ret) { 363 switch (ret) {
364 case 0:
365 afs_stat_v(vnode, n_stores);
366 atomic_long_add((last * PAGE_SIZE + to) -
367 (first * PAGE_SIZE + offset),
368 &afs_v2net(vnode)->n_store_bytes);
369 break;
358 case -EACCES: 370 case -EACCES:
359 case -EPERM: 371 case -EPERM:
360 case -ENOKEY: 372 case -ENOKEY:
@@ -412,7 +424,8 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
412 trace_afs_page_dirty(vnode, tracepoint_string("WARN"), 424 trace_afs_page_dirty(vnode, tracepoint_string("WARN"),
413 primary_page->index, priv); 425 primary_page->index, priv);
414 426
415 if (start >= final_page || to < PAGE_SIZE) 427 if (start >= final_page ||
428 (to < PAGE_SIZE && !test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags)))
416 goto no_more; 429 goto no_more;
417 430
418 start++; 431 start++;
@@ -433,9 +446,10 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
433 } 446 }
434 447
435 for (loop = 0; loop < n; loop++) { 448 for (loop = 0; loop < n; loop++) {
436 if (to != PAGE_SIZE)
437 break;
438 page = pages[loop]; 449 page = pages[loop];
450 if (to != PAGE_SIZE &&
451 !test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags))
452 break;
439 if (page->index > final_page) 453 if (page->index > final_page)
440 break; 454 break;
441 if (!trylock_page(page)) 455 if (!trylock_page(page))
@@ -448,7 +462,8 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
448 priv = page_private(page); 462 priv = page_private(page);
449 f = priv & AFS_PRIV_MAX; 463 f = priv & AFS_PRIV_MAX;
450 t = priv >> AFS_PRIV_SHIFT; 464 t = priv >> AFS_PRIV_SHIFT;
451 if (f != 0) { 465 if (f != 0 &&
466 !test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags)) {
452 unlock_page(page); 467 unlock_page(page);
453 break; 468 break;
454 } 469 }
@@ -735,20 +750,6 @@ int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
735} 750}
736 751
737/* 752/*
738 * Flush out all outstanding writes on a file opened for writing when it is
739 * closed.
740 */
741int afs_flush(struct file *file, fl_owner_t id)
742{
743 _enter("");
744
745 if ((file->f_mode & FMODE_WRITE) == 0)
746 return 0;
747
748 return vfs_fsync(file, 0);
749}
750
751/*
752 * notification that a previously read-only page is about to become writable 753 * notification that a previously read-only page is about to become writable
753 * - if it returns an error, the caller will deliver a bus error signal 754 * - if it returns an error, the caller will deliver a bus error signal
754 */ 755 */
diff --git a/fs/afs/xdr_fs.h b/fs/afs/xdr_fs.h
new file mode 100644
index 000000000000..aa21f3068d52
--- /dev/null
+++ b/fs/afs/xdr_fs.h
@@ -0,0 +1,103 @@
1/* AFS fileserver XDR types
2 *
3 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef XDR_FS_H
13#define XDR_FS_H
14
15struct afs_xdr_AFSFetchStatus {
16 __be32 if_version;
17#define AFS_FSTATUS_VERSION 1
18 __be32 type;
19 __be32 nlink;
20 __be32 size_lo;
21 __be32 data_version_lo;
22 __be32 author;
23 __be32 owner;
24 __be32 caller_access;
25 __be32 anon_access;
26 __be32 mode;
27 __be32 parent_vnode;
28 __be32 parent_unique;
29 __be32 seg_size;
30 __be32 mtime_client;
31 __be32 mtime_server;
32 __be32 group;
33 __be32 sync_counter;
34 __be32 data_version_hi;
35 __be32 lock_count;
36 __be32 size_hi;
37 __be32 abort_code;
38} __packed;
39
40#define AFS_DIR_HASHTBL_SIZE 128
41#define AFS_DIR_DIRENT_SIZE 32
42#define AFS_DIR_SLOTS_PER_BLOCK 64
43#define AFS_DIR_BLOCK_SIZE 2048
44#define AFS_DIR_BLOCKS_PER_PAGE (PAGE_SIZE / AFS_DIR_BLOCK_SIZE)
45#define AFS_DIR_MAX_SLOTS 65536
46#define AFS_DIR_BLOCKS_WITH_CTR 128
47#define AFS_DIR_MAX_BLOCKS 1023
48#define AFS_DIR_RESV_BLOCKS 1
49#define AFS_DIR_RESV_BLOCKS0 13
50
51/*
52 * Directory entry structure.
53 */
54union afs_xdr_dirent {
55 struct {
56 u8 valid;
57 u8 unused[1];
58 __be16 hash_next;
59 __be32 vnode;
60 __be32 unique;
61 u8 name[16];
62 u8 overflow[4]; /* if any char of the name (inc
63 * NUL) reaches here, consume
64 * the next dirent too */
65 } u;
66 u8 extended_name[32];
67} __packed;
68
69/*
70 * Directory block header (one at the beginning of every 2048-byte block).
71 */
72struct afs_xdr_dir_hdr {
73 __be16 npages;
74 __be16 magic;
75#define AFS_DIR_MAGIC htons(1234)
76 u8 reserved;
77 u8 bitmap[8];
78 u8 pad[19];
79} __packed;
80
81/*
82 * Directory block layout
83 */
84union afs_xdr_dir_block {
85 struct afs_xdr_dir_hdr hdr;
86
87 struct {
88 struct afs_xdr_dir_hdr hdr;
89 u8 alloc_ctrs[AFS_DIR_MAX_BLOCKS];
90 __be16 hashtable[AFS_DIR_HASHTBL_SIZE];
91 } meta;
92
93 union afs_xdr_dirent dirents[AFS_DIR_SLOTS_PER_BLOCK];
94} __packed;
95
96/*
97 * Directory layout on a linux VM page.
98 */
99struct afs_xdr_dir_page {
100 union afs_xdr_dir_block blocks[AFS_DIR_BLOCKS_PER_PAGE];
101};
102
103#endif /* XDR_FS_H */