Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+2709 -599
+27 -1
Documentation/filesystems/afs.txt
··· 11 11 - Proc filesystem. 12 12 - The cell database. 13 13 - Security. 14 - - Examples. 14 + - The @sys substitution. 15 15 16 16 17 17 ======== ··· 230 230 passed to a process that doesn't have that key (perhaps over an AF_UNIX 231 231 socket), then the operations on the file will be made with key that was used to 232 232 open the file. 233 + 234 + 235 + ===================== 236 + THE @SYS SUBSTITUTION 237 + ===================== 238 + 239 + The list of up to 16 @sys substitutions for the current network namespace can 240 + be configured by writing a list to /proc/fs/afs/sysname: 241 + 242 + [root@andromeda ~]# echo foo amd64_linux_26 >/proc/fs/afs/sysname 243 + 244 + or cleared entirely by writing an empty list: 245 + 246 + [root@andromeda ~]# echo >/proc/fs/afs/sysname 247 + 248 + The current list for current network namespace can be retrieved by: 249 + 250 + [root@andromeda ~]# cat /proc/fs/afs/sysname 251 + foo 252 + amd64_linux_26 253 + 254 + When @sys is being substituted for, each element of the list is tried in the 255 + order given. 256 + 257 + By default, the list will contain one item that conforms to the pattern 258 + "<arch>_linux_26", amd64 being the name for x86_64.
+2
fs/afs/Makefile
··· 12 12 cell.o \ 13 13 cmservice.o \ 14 14 dir.o \ 15 + dir_edit.o \ 16 + dynroot.o \ 15 17 file.o \ 16 18 flock.o \ 17 19 fsclient.o \
+3 -3
fs/afs/addr_list.c
··· 243 243 xport == a->sin6_port) 244 244 return; 245 245 if (xdr == a->sin6_addr.s6_addr32[3] && 246 - xport < a->sin6_port) 246 + (u16 __force)xport < (u16 __force)a->sin6_port) 247 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 249 break; 250 250 } 251 251 ··· 280 280 xport == a->sin6_port) 281 281 return; 282 282 if (diff == 0 && 283 - xport < a->sin6_port) 283 + (u16 __force)xport < (u16 __force)a->sin6_port) 284 284 break; 285 285 if (diff < 0) 286 286 break;
+15 -12
fs/afs/afs.h
··· 67 67 } afs_callback_type_t; 68 68 69 69 struct afs_callback { 70 - struct afs_fid fid; /* file identifier */ 71 - unsigned version; /* callback version */ 72 - unsigned expiry; /* time at which expires */ 73 - afs_callback_type_t type; /* type of callback */ 70 + unsigned version; /* Callback version */ 71 + unsigned expiry; /* Time at which expires */ 72 + afs_callback_type_t type; /* Type of callback */ 73 + }; 74 + 75 + struct afs_callback_break { 76 + struct afs_fid fid; /* File identifier */ 77 + struct afs_callback cb; /* Callback details */ 74 78 }; 75 79 76 80 #define AFSCBMAX 50 /* maximum callbacks transferred per bulk op */ ··· 127 123 * AFS file status information 128 124 */ 129 125 struct afs_file_status { 130 - unsigned if_version; /* interface version */ 131 - #define AFS_FSTATUS_VERSION 1 126 + u64 size; /* file size */ 127 + afs_dataversion_t data_version; /* current data version */ 128 + time_t mtime_client; /* last time client changed data */ 129 + time_t mtime_server; /* last time server changed data */ 130 + unsigned abort_code; /* Abort if bulk-fetching this failed */ 132 131 133 132 afs_file_type_t type; /* file type */ 134 133 unsigned nlink; /* link count */ 135 - u64 size; /* file size */ 136 - afs_dataversion_t data_version; /* current data version */ 137 134 u32 author; /* author ID */ 138 - kuid_t owner; /* owner ID */ 139 - kgid_t group; /* group ID */ 135 + u32 owner; /* owner ID */ 136 + u32 group; /* group ID */ 140 137 afs_access_t caller_access; /* access rights for authenticated caller */ 141 138 afs_access_t anon_access; /* access rights for unauthenticated caller */ 142 139 umode_t mode; /* UNIX mode */ 143 - time_t mtime_client; /* last time client changed data */ 144 - time_t mtime_server; /* last time server changed data */ 145 140 s32 lock_count; /* file lock count (0=UNLK -1=WRLCK +ve=#RDLCK */ 146 141 }; 147 142
+2
fs/afs/afs_fs.h
··· 31 31 FSGETVOLUMEINFO = 148, /* AFS Get information about a volume */ 32 32 FSGETVOLUMESTATUS = 149, /* AFS Get volume status information */ 33 33 FSGETROOTVOLUME = 151, /* AFS Get root volume name */ 34 + FSBULKSTATUS = 155, /* AFS Fetch multiple file statuses */ 34 35 FSSETLOCK = 156, /* AFS Request a file lock */ 35 36 FSEXTENDLOCK = 157, /* AFS Extend a file lock */ 36 37 FSRELEASELOCK = 158, /* AFS Release a file lock */ 37 38 FSLOOKUP = 161, /* AFS lookup file in directory */ 39 + FSINLINEBULKSTATUS = 65536, /* AFS Fetch multiple file statuses with inline errors */ 38 40 FSFETCHDATA64 = 65537, /* AFS Fetch file data */ 39 41 FSSTOREDATA64 = 65538, /* AFS Store file data */ 40 42 FSGIVEUPALLCALLBACKS = 65539, /* AFS Give up all outstanding callbacks on a server */
+5 -24
fs/afs/callback.c
··· 97 97 } 98 98 99 99 /* 100 - * Set a vnode's interest on a server. 101 - */ 102 - void 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 100 * Remove an interest on a server. 121 101 */ 122 102 void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi) ··· 130 150 131 151 write_seqlock(&vnode->cb_lock); 132 152 153 + clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 133 154 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { 134 155 vnode->cb_break++; 135 156 afs_clear_permits(vnode); ··· 188 207 * allow the fileserver to break callback promises 189 208 */ 190 209 void afs_break_callbacks(struct afs_server *server, size_t count, 191 - struct afs_callback callbacks[]) 210 + struct afs_callback_break *callbacks) 192 211 { 193 212 _enter("%p,%zu,", server, count); 194 213 ··· 200 219 callbacks->fid.vid, 201 220 callbacks->fid.vnode, 202 221 callbacks->fid.unique, 203 - callbacks->version, 204 - callbacks->expiry, 205 - callbacks->type 222 + callbacks->cb.version, 223 + callbacks->cb.expiry, 224 + callbacks->cb.type 206 225 ); 207 226 afs_break_one_callback(server, &callbacks->fid); 208 227 }
+7 -5
fs/afs/cell.c
··· 18 18 #include <keys/rxrpc-type.h> 19 19 #include "internal.h" 20 20 21 - unsigned __read_mostly afs_cell_gc_delay = 10; 21 + static unsigned __read_mostly afs_cell_gc_delay = 10; 22 22 23 23 static void afs_manage_cell(struct work_struct *); 24 24 ··· 75 75 cell = rcu_dereference_raw(net->ws_cell); 76 76 if (cell) { 77 77 afs_get_cell(cell); 78 - continue; 78 + break; 79 79 } 80 80 ret = -EDESTADDRREQ; 81 81 continue; ··· 130 130 _leave(" = -ENAMETOOLONG"); 131 131 return ERR_PTR(-ENAMETOOLONG); 132 132 } 133 + if (namelen == 5 && memcmp(name, "@cell", 5) == 0) 134 + return ERR_PTR(-EINVAL); 133 135 134 136 _enter("%*.*s,%s", namelen, namelen, name, vllist); 135 137 ··· 336 334 return PTR_ERR(new_root); 337 335 } 338 336 339 - set_bit(AFS_CELL_FL_NO_GC, &new_root->flags); 340 - afs_get_cell(new_root); 337 + if (!test_and_set_bit(AFS_CELL_FL_NO_GC, &new_root->flags)) 338 + afs_get_cell(new_root); 341 339 342 340 /* install the new cell */ 343 341 write_seqlock(&net->cells_lock); ··· 413 411 414 412 ASSERTCMP(atomic_read(&cell->usage), ==, 0); 415 413 416 - afs_put_addrlist(cell->vl_addrs); 414 + afs_put_addrlist(rcu_access_pointer(cell->vl_addrs)); 417 415 key_put(cell->anonymous_key); 418 416 kfree(cell); 419 417
+11 -11
fs/afs/cmservice.c
··· 178 178 */ 179 179 static int afs_deliver_cb_callback(struct afs_call *call) 180 180 { 181 + struct afs_callback_break *cb; 181 182 struct sockaddr_rxrpc srx; 182 - struct afs_callback *cb; 183 183 struct afs_server *server; 184 184 __be32 *bp; 185 185 int ret, loop; ··· 201 201 call->count = ntohl(call->tmp); 202 202 _debug("FID count: %u", call->count); 203 203 if (call->count > AFSCBMAX) 204 - return -EBADMSG; 204 + return afs_protocol_error(call, -EBADMSG); 205 205 206 206 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL); 207 207 if (!call->buffer) ··· 218 218 219 219 _debug("unmarshall FID array"); 220 220 call->request = kcalloc(call->count, 221 - sizeof(struct afs_callback), 221 + sizeof(struct afs_callback_break), 222 222 GFP_KERNEL); 223 223 if (!call->request) 224 224 return -ENOMEM; ··· 229 229 cb->fid.vid = ntohl(*bp++); 230 230 cb->fid.vnode = ntohl(*bp++); 231 231 cb->fid.unique = ntohl(*bp++); 232 - cb->type = AFSCM_CB_UNTYPED; 232 + cb->cb.type = AFSCM_CB_UNTYPED; 233 233 } 234 234 235 235 call->offset = 0; ··· 245 245 call->count2 = ntohl(call->tmp); 246 246 _debug("CB count: %u", call->count2); 247 247 if (call->count2 != call->count && call->count2 != 0) 248 - return -EBADMSG; 248 + return afs_protocol_error(call, -EBADMSG); 249 249 call->offset = 0; 250 250 call->unmarshall++; 251 251 ··· 260 260 cb = call->request; 261 261 bp = call->buffer; 262 262 for (loop = call->count2; loop > 0; loop--, cb++) { 263 - cb->version = ntohl(*bp++); 264 - cb->expiry = ntohl(*bp++); 265 - cb->type = ntohl(*bp++); 263 + cb->cb.version = ntohl(*bp++); 264 + cb->cb.expiry = ntohl(*bp++); 265 + cb->cb.type = ntohl(*bp++); 266 266 } 267 267 268 268 call->offset = 0; ··· 500 500 501 501 b = call->buffer; 502 502 r = call->request; 503 - r->time_low = ntohl(b[0]); 504 - r->time_mid = ntohl(b[1]); 505 - r->time_hi_and_version = ntohl(b[2]); 503 + r->time_low = b[0]; 504 + r->time_mid = htons(ntohl(b[1])); 505 + r->time_hi_and_version = htons(ntohl(b[2])); 506 506 r->clock_seq_hi_and_reserved = ntohl(b[3]); 507 507 r->clock_seq_low = ntohl(b[4]); 508 508
+637 -296
fs/afs/dir.c
··· 1 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 4 * Written by David Howells (dhowells@redhat.com) 5 5 * 6 6 * This program is free software; you can redistribute it and/or ··· 10 10 */ 11 11 12 12 #include <linux/kernel.h> 13 - #include <linux/module.h> 14 - #include <linux/init.h> 15 13 #include <linux/fs.h> 16 14 #include <linux/namei.h> 17 15 #include <linux/pagemap.h> 16 + #include <linux/swap.h> 18 17 #include <linux/ctype.h> 19 18 #include <linux/sched.h> 20 - #include <linux/dns_resolver.h> 19 + #include <linux/task_io_accounting_ops.h> 21 20 #include "internal.h" 21 + #include "xdr_fs.h" 22 22 23 23 static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, 24 24 unsigned int flags); 25 - static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry, 26 - unsigned int flags); 27 25 static int afs_dir_open(struct inode *inode, struct file *file); 28 26 static int afs_readdir(struct file *file, struct dir_context *ctx); 29 27 static int afs_d_revalidate(struct dentry *dentry, unsigned int flags); 30 28 static int afs_d_delete(const struct dentry *dentry); 31 - static void afs_d_release(struct dentry *dentry); 32 - static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen, 29 + static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen, 33 30 loff_t fpos, u64 ino, unsigned dtype); 31 + static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen, 32 + loff_t fpos, u64 ino, unsigned dtype); 34 33 static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode, 35 34 bool excl); 36 35 static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); ··· 42 43 static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, 43 44 struct inode *new_dir, struct dentry *new_dentry, 44 45 unsigned int flags); 46 + static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags); 47 + static void afs_dir_invalidatepage(struct page *page, unsigned int offset, 48 + unsigned int length); 49 + 50 + static int afs_dir_set_page_dirty(struct page *page) 51 + { 52 + BUG(); /* This should never happen. */ 53 + } 45 54 46 55 const struct file_operations afs_dir_file_operations = { 47 56 .open = afs_dir_open, ··· 74 67 .listxattr = afs_listxattr, 75 68 }; 76 69 77 - const struct file_operations afs_dynroot_file_operations = { 78 - .open = dcache_dir_open, 79 - .release = dcache_dir_close, 80 - .iterate_shared = dcache_readdir, 81 - .llseek = dcache_dir_lseek, 82 - }; 83 - 84 - const struct inode_operations afs_dynroot_inode_operations = { 85 - .lookup = afs_dynroot_lookup, 70 + const struct address_space_operations afs_dir_aops = { 71 + .set_page_dirty = afs_dir_set_page_dirty, 72 + .releasepage = afs_dir_releasepage, 73 + .invalidatepage = afs_dir_invalidatepage, 86 74 }; 87 75 88 76 const struct dentry_operations afs_fs_dentry_operations = { ··· 87 85 .d_automount = afs_d_automount, 88 86 }; 89 87 90 - #define AFS_DIR_HASHTBL_SIZE 128 91 - #define AFS_DIR_DIRENT_SIZE 32 92 - #define AFS_DIRENT_PER_BLOCK 64 93 - 94 - union afs_dirent { 95 - struct { 96 - uint8_t valid; 97 - uint8_t unused[1]; 98 - __be16 hash_next; 99 - __be32 vnode; 100 - __be32 unique; 101 - uint8_t name[16]; 102 - uint8_t overflow[4]; /* if any char of the name (inc 103 - * NUL) reaches here, consume 104 - * the next dirent too */ 105 - } u; 106 - uint8_t extended_name[32]; 107 - }; 108 - 109 - /* AFS directory page header (one at the beginning of every 2048-byte chunk) */ 110 - struct afs_dir_pagehdr { 111 - __be16 npages; 112 - __be16 magic; 113 - #define AFS_DIR_MAGIC htons(1234) 114 - uint8_t nentries; 115 - uint8_t bitmap[8]; 116 - uint8_t pad[19]; 117 - }; 118 - 119 - /* directory block layout */ 120 - union afs_dir_block { 121 - 122 - struct afs_dir_pagehdr pagehdr; 123 - 124 - struct { 125 - struct afs_dir_pagehdr pagehdr; 126 - uint8_t alloc_ctrs[128]; 127 - /* dir hash table */ 128 - uint16_t hashtable[AFS_DIR_HASHTBL_SIZE]; 129 - } hdr; 130 - 131 - union afs_dirent dirents[AFS_DIRENT_PER_BLOCK]; 132 - }; 133 - 134 - /* layout on a linux VM page */ 135 - struct afs_dir_page { 136 - union afs_dir_block blocks[PAGE_SIZE / sizeof(union afs_dir_block)]; 88 + struct afs_lookup_one_cookie { 89 + struct dir_context ctx; 90 + struct qstr name; 91 + bool found; 92 + struct afs_fid fid; 137 93 }; 138 94 139 95 struct afs_lookup_cookie { 140 - struct dir_context ctx; 141 - struct afs_fid fid; 142 - struct qstr name; 143 - int found; 96 + struct dir_context ctx; 97 + struct qstr name; 98 + bool found; 99 + bool one_only; 100 + unsigned short nr_fids; 101 + struct afs_file_status *statuses; 102 + struct afs_callback *callbacks; 103 + struct afs_fid fids[50]; 144 104 }; 145 105 146 106 /* 147 107 * check that a directory page is valid 148 108 */ 149 - bool afs_dir_check_page(struct inode *dir, struct page *page) 109 + static bool afs_dir_check_page(struct afs_vnode *dvnode, struct page *page, 110 + loff_t i_size) 150 111 { 151 - struct afs_dir_page *dbuf; 152 - struct afs_vnode *vnode = AFS_FS_I(dir); 153 - loff_t latter, i_size, off; 112 + struct afs_xdr_dir_page *dbuf; 113 + loff_t latter, off; 154 114 int tmp, qty; 155 - 156 - #if 0 157 - /* check the page count */ 158 - qty = desc.size / sizeof(dbuf->blocks[0]); 159 - if (qty == 0) 160 - goto error; 161 - 162 - if (page->index == 0 && qty != ntohs(dbuf->blocks[0].pagehdr.npages)) { 163 - printk("kAFS: %s(%lu): wrong number of dir blocks %d!=%hu\n", 164 - __func__, dir->i_ino, qty, 165 - ntohs(dbuf->blocks[0].pagehdr.npages)); 166 - goto error; 167 - } 168 - #endif 169 115 170 116 /* Determine how many magic numbers there should be in this page, but 171 117 * we must take care because the directory may change size under us. 172 118 */ 173 119 off = page_offset(page); 174 - i_size = i_size_read(dir); 175 120 if (i_size <= off) 176 121 goto checked; 177 122 ··· 127 178 qty = PAGE_SIZE; 128 179 else 129 180 qty = latter; 130 - qty /= sizeof(union afs_dir_block); 181 + qty /= sizeof(union afs_xdr_dir_block); 131 182 132 183 /* check them */ 133 - dbuf = page_address(page); 184 + dbuf = kmap(page); 134 185 for (tmp = 0; tmp < qty; tmp++) { 135 - if (dbuf->blocks[tmp].pagehdr.magic != AFS_DIR_MAGIC) { 186 + if (dbuf->blocks[tmp].hdr.magic != AFS_DIR_MAGIC) { 136 187 printk("kAFS: %s(%lx): bad magic %d/%d is %04hx\n", 137 - __func__, dir->i_ino, tmp, qty, 138 - ntohs(dbuf->blocks[tmp].pagehdr.magic)); 139 - trace_afs_dir_check_failed(vnode, off, i_size); 188 + __func__, dvnode->vfs_inode.i_ino, tmp, qty, 189 + ntohs(dbuf->blocks[tmp].hdr.magic)); 190 + trace_afs_dir_check_failed(dvnode, off, i_size); 191 + kunmap(page); 140 192 goto error; 141 193 } 194 + 195 + /* Make sure each block is NUL terminated so we can reasonably 196 + * use string functions on it. The filenames in the page 197 + * *should* be NUL-terminated anyway. 198 + */ 199 + ((u8 *)&dbuf->blocks[tmp])[AFS_DIR_BLOCK_SIZE - 1] = 0; 142 200 } 143 201 202 + kunmap(page); 203 + 144 204 checked: 145 - SetPageChecked(page); 205 + afs_stat_v(dvnode, n_read_dir); 146 206 return true; 147 207 148 208 error: 149 - SetPageError(page); 150 209 return false; 151 - } 152 - 153 - /* 154 - * discard a page cached in the pagecache 155 - */ 156 - static inline void afs_dir_put_page(struct page *page) 157 - { 158 - kunmap(page); 159 - unlock_page(page); 160 - put_page(page); 161 - } 162 - 163 - /* 164 - * get a page into the pagecache 165 - */ 166 - static struct page *afs_dir_get_page(struct inode *dir, unsigned long index, 167 - struct key *key) 168 - { 169 - struct page *page; 170 - _enter("{%lu},%lu", dir->i_ino, index); 171 - 172 - page = read_cache_page(dir->i_mapping, index, afs_page_filler, key); 173 - if (!IS_ERR(page)) { 174 - lock_page(page); 175 - kmap(page); 176 - if (unlikely(!PageChecked(page))) { 177 - if (PageError(page)) 178 - goto fail; 179 - } 180 - } 181 - return page; 182 - 183 - fail: 184 - afs_dir_put_page(page); 185 - _leave(" = -EIO"); 186 - return ERR_PTR(-EIO); 187 210 } 188 211 189 212 /* ··· 165 244 { 166 245 _enter("{%lu}", inode->i_ino); 167 246 168 - BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048); 169 - BUILD_BUG_ON(sizeof(union afs_dirent) != 32); 247 + BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048); 248 + BUILD_BUG_ON(sizeof(union afs_xdr_dirent) != 32); 170 249 171 250 if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags)) 172 251 return -ENOENT; ··· 175 254 } 176 255 177 256 /* 257 + * Read the directory into the pagecache in one go, scrubbing the previous 258 + * contents. The list of pages is returned, pinning them so that they don't 259 + * get reclaimed during the iteration. 260 + */ 261 + static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key) 262 + { 263 + struct afs_read *req; 264 + loff_t i_size; 265 + int nr_pages, nr_inline, i, n; 266 + int ret = -ENOMEM; 267 + 268 + retry: 269 + i_size = i_size_read(&dvnode->vfs_inode); 270 + if (i_size < 2048) 271 + return ERR_PTR(-EIO); 272 + if (i_size > 2048 * 1024) 273 + return ERR_PTR(-EFBIG); 274 + 275 + _enter("%llu", i_size); 276 + 277 + /* Get a request record to hold the page list. We want to hold it 278 + * inline if we can, but we don't want to make an order 1 allocation. 279 + */ 280 + nr_pages = (i_size + PAGE_SIZE - 1) / PAGE_SIZE; 281 + nr_inline = nr_pages; 282 + if (nr_inline > (PAGE_SIZE - sizeof(*req)) / sizeof(struct page *)) 283 + nr_inline = 0; 284 + 285 + req = kzalloc(sizeof(*req) + sizeof(struct page *) * nr_inline, 286 + GFP_KERNEL); 287 + if (!req) 288 + return ERR_PTR(-ENOMEM); 289 + 290 + refcount_set(&req->usage, 1); 291 + req->nr_pages = nr_pages; 292 + req->actual_len = i_size; /* May change */ 293 + req->len = nr_pages * PAGE_SIZE; /* We can ask for more than there is */ 294 + req->data_version = dvnode->status.data_version; /* May change */ 295 + if (nr_inline > 0) { 296 + req->pages = req->array; 297 + } else { 298 + req->pages = kcalloc(nr_pages, sizeof(struct page *), 299 + GFP_KERNEL); 300 + if (!req->pages) 301 + goto error; 302 + } 303 + 304 + /* Get a list of all the pages that hold or will hold the directory 305 + * content. We need to fill in any gaps that we might find where the 306 + * memory reclaimer has been at work. If there are any gaps, we will 307 + * need to reread the entire directory contents. 308 + */ 309 + i = 0; 310 + do { 311 + n = find_get_pages_contig(dvnode->vfs_inode.i_mapping, i, 312 + req->nr_pages - i, 313 + req->pages + i); 314 + _debug("find %u at %u/%u", n, i, req->nr_pages); 315 + if (n == 0) { 316 + gfp_t gfp = dvnode->vfs_inode.i_mapping->gfp_mask; 317 + 318 + if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 319 + afs_stat_v(dvnode, n_inval); 320 + 321 + ret = -ENOMEM; 322 + req->pages[i] = __page_cache_alloc(gfp); 323 + if (!req->pages[i]) 324 + goto error; 325 + ret = add_to_page_cache_lru(req->pages[i], 326 + dvnode->vfs_inode.i_mapping, 327 + i, gfp); 328 + if (ret < 0) 329 + goto error; 330 + 331 + set_page_private(req->pages[i], 1); 332 + SetPagePrivate(req->pages[i]); 333 + unlock_page(req->pages[i]); 334 + i++; 335 + } else { 336 + i += n; 337 + } 338 + } while (i < req->nr_pages); 339 + 340 + /* If we're going to reload, we need to lock all the pages to prevent 341 + * races. 342 + */ 343 + if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { 344 + ret = -ERESTARTSYS; 345 + for (i = 0; i < req->nr_pages; i++) 346 + if (lock_page_killable(req->pages[i]) < 0) 347 + goto error_unlock; 348 + 349 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 350 + goto success; 351 + 352 + ret = afs_fetch_data(dvnode, key, req); 353 + if (ret < 0) 354 + goto error_unlock_all; 355 + 356 + task_io_account_read(PAGE_SIZE * req->nr_pages); 357 + 358 + if (req->len < req->file_size) 359 + goto content_has_grown; 360 + 361 + /* Validate the data we just read. */ 362 + ret = -EIO; 363 + for (i = 0; i < req->nr_pages; i++) 364 + if (!afs_dir_check_page(dvnode, req->pages[i], 365 + req->actual_len)) 366 + goto error_unlock_all; 367 + 368 + // TODO: Trim excess pages 369 + 370 + set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags); 371 + } 372 + 373 + success: 374 + i = req->nr_pages; 375 + while (i > 0) 376 + unlock_page(req->pages[--i]); 377 + return req; 378 + 379 + error_unlock_all: 380 + i = req->nr_pages; 381 + error_unlock: 382 + while (i > 0) 383 + unlock_page(req->pages[--i]); 384 + error: 385 + afs_put_read(req); 386 + _leave(" = %d", ret); 387 + return ERR_PTR(ret); 388 + 389 + content_has_grown: 390 + i = req->nr_pages; 391 + while (i > 0) 392 + unlock_page(req->pages[--i]); 393 + afs_put_read(req); 394 + goto retry; 395 + } 396 + 397 + /* 178 398 * deal with one block in an AFS directory 179 399 */ 180 400 static int afs_dir_iterate_block(struct dir_context *ctx, 181 - union afs_dir_block *block, 401 + union afs_xdr_dir_block *block, 182 402 unsigned blkoff) 183 403 { 184 - union afs_dirent *dire; 404 + union afs_xdr_dirent *dire; 185 405 unsigned offset, next, curr; 186 406 size_t nlen; 187 407 int tmp; 188 408 189 409 _enter("%u,%x,%p,,",(unsigned)ctx->pos,blkoff,block); 190 410 191 - curr = (ctx->pos - blkoff) / sizeof(union afs_dirent); 411 + curr = (ctx->pos - blkoff) / sizeof(union afs_xdr_dirent); 192 412 193 413 /* walk through the block, an entry at a time */ 194 - for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries; 195 - offset < AFS_DIRENT_PER_BLOCK; 414 + for (offset = (blkoff == 0 ? AFS_DIR_RESV_BLOCKS0 : AFS_DIR_RESV_BLOCKS); 415 + offset < AFS_DIR_SLOTS_PER_BLOCK; 196 416 offset = next 197 417 ) { 198 418 next = offset + 1; 199 419 200 420 /* skip entries marked unused in the bitmap */ 201 - if (!(block->pagehdr.bitmap[offset / 8] & 421 + if (!(block->hdr.bitmap[offset / 8] & 202 422 (1 << (offset % 8)))) { 203 423 _debug("ENT[%zu.%u]: unused", 204 - blkoff / sizeof(union afs_dir_block), offset); 424 + blkoff / sizeof(union afs_xdr_dir_block), offset); 205 425 if (offset >= curr) 206 426 ctx->pos = blkoff + 207 - next * sizeof(union afs_dirent); 427 + next * sizeof(union afs_xdr_dirent); 208 428 continue; 209 429 } 210 430 ··· 353 291 dire = &block->dirents[offset]; 354 292 nlen = strnlen(dire->u.name, 355 293 sizeof(*block) - 356 - offset * sizeof(union afs_dirent)); 294 + offset * sizeof(union afs_xdr_dirent)); 357 295 358 296 _debug("ENT[%zu.%u]: %s %zu \"%s\"", 359 - blkoff / sizeof(union afs_dir_block), offset, 297 + blkoff / sizeof(union afs_xdr_dir_block), offset, 360 298 (offset < curr ? "skip" : "fill"), 361 299 nlen, dire->u.name); 362 300 363 301 /* work out where the next possible entry is */ 364 - for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_dirent)) { 365 - if (next >= AFS_DIRENT_PER_BLOCK) { 302 + for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_xdr_dirent)) { 303 + if (next >= AFS_DIR_SLOTS_PER_BLOCK) { 366 304 _debug("ENT[%zu.%u]:" 367 305 " %u travelled beyond end dir block" 368 306 " (len %u/%zu)", 369 - blkoff / sizeof(union afs_dir_block), 307 + blkoff / sizeof(union afs_xdr_dir_block), 370 308 offset, next, tmp, nlen); 371 309 return -EIO; 372 310 } 373 - if (!(block->pagehdr.bitmap[next / 8] & 311 + if (!(block->hdr.bitmap[next / 8] & 374 312 (1 << (next % 8)))) { 375 313 _debug("ENT[%zu.%u]:" 376 314 " %u unmarked extension (len %u/%zu)", 377 - blkoff / sizeof(union afs_dir_block), 315 + blkoff / sizeof(union afs_xdr_dir_block), 378 316 offset, next, tmp, nlen); 379 317 return -EIO; 380 318 } 381 319 382 320 _debug("ENT[%zu.%u]: ext %u/%zu", 383 - blkoff / sizeof(union afs_dir_block), 321 + blkoff / sizeof(union afs_xdr_dir_block), 384 322 next, tmp, nlen); 385 323 next++; 386 324 } ··· 392 330 /* found the next entry */ 393 331 if (!dir_emit(ctx, dire->u.name, nlen, 394 332 ntohl(dire->u.vnode), 395 - ctx->actor == afs_lookup_filldir ? 333 + (ctx->actor == afs_lookup_filldir || 334 + ctx->actor == afs_lookup_one_filldir)? 396 335 ntohl(dire->u.unique) : DT_UNKNOWN)) { 397 336 _leave(" = 0 [full]"); 398 337 return 0; 399 338 } 400 339 401 - ctx->pos = blkoff + next * sizeof(union afs_dirent); 340 + ctx->pos = blkoff + next * sizeof(union afs_xdr_dirent); 402 341 } 403 342 404 343 _leave(" = 1 [more]"); ··· 412 349 static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx, 413 350 struct key *key) 414 351 { 415 - union afs_dir_block *dblock; 416 - struct afs_dir_page *dbuf; 352 + struct afs_vnode *dvnode = AFS_FS_I(dir); 353 + struct afs_xdr_dir_page *dbuf; 354 + union afs_xdr_dir_block *dblock; 355 + struct afs_read *req; 417 356 struct page *page; 418 357 unsigned blkoff, limit; 419 358 int ret; ··· 427 362 return -ESTALE; 428 363 } 429 364 365 + req = afs_read_dir(dvnode, key); 366 + if (IS_ERR(req)) 367 + return PTR_ERR(req); 368 + 430 369 /* round the file position up to the next entry boundary */ 431 - ctx->pos += sizeof(union afs_dirent) - 1; 432 - ctx->pos &= ~(sizeof(union afs_dirent) - 1); 370 + ctx->pos += sizeof(union afs_xdr_dirent) - 1; 371 + ctx->pos &= ~(sizeof(union afs_xdr_dirent) - 1); 433 372 434 373 /* walk through the blocks in sequence */ 435 374 ret = 0; 436 - while (ctx->pos < dir->i_size) { 437 - blkoff = ctx->pos & ~(sizeof(union afs_dir_block) - 1); 375 + while (ctx->pos < req->actual_len) { 376 + blkoff = ctx->pos & ~(sizeof(union afs_xdr_dir_block) - 1); 438 377 439 - /* fetch the appropriate page from the directory */ 440 - page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key); 441 - if (IS_ERR(page)) { 442 - ret = PTR_ERR(page); 378 + /* Fetch the appropriate page from the directory and re-add it 379 + * to the LRU. 380 + */ 381 + page = req->pages[blkoff / PAGE_SIZE]; 382 + if (!page) { 383 + ret = -EIO; 443 384 break; 444 385 } 386 + mark_page_accessed(page); 445 387 446 388 limit = blkoff & ~(PAGE_SIZE - 1); 447 389 448 - dbuf = page_address(page); 390 + dbuf = kmap(page); 449 391 450 392 /* deal with the individual blocks stashed on this page */ 451 393 do { 452 394 dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) / 453 - sizeof(union afs_dir_block)]; 395 + sizeof(union afs_xdr_dir_block)]; 454 396 ret = afs_dir_iterate_block(ctx, dblock, blkoff); 455 397 if (ret != 1) { 456 - afs_dir_put_page(page); 398 + kunmap(page); 457 399 goto out; 458 400 } 459 401 460 - blkoff += sizeof(union afs_dir_block); 402 + blkoff += sizeof(union afs_xdr_dir_block); 461 403 462 404 } while (ctx->pos < dir->i_size && blkoff < limit); 463 405 464 - afs_dir_put_page(page); 406 + kunmap(page); 465 407 ret = 0; 466 408 } 467 409 468 410 out: 411 + afs_put_read(req); 469 412 _leave(" = %d", ret); 470 413 return ret; 471 414 } ··· 487 414 } 488 415 489 416 /* 490 - * search the directory for a name 417 + * Search the directory for a single name 491 418 * - if afs_dir_iterate_block() spots this function, it'll pass the FID 492 419 * uniquifier through dtype 493 420 */ 494 - static int afs_lookup_filldir(struct dir_context *ctx, const char *name, 495 - int nlen, loff_t fpos, u64 ino, unsigned dtype) 421 + static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, 422 + int nlen, loff_t fpos, u64 ino, unsigned dtype) 496 423 { 497 - struct afs_lookup_cookie *cookie = 498 - container_of(ctx, struct afs_lookup_cookie, ctx); 424 + struct afs_lookup_one_cookie *cookie = 425 + container_of(ctx, struct afs_lookup_one_cookie, ctx); 499 426 500 427 _enter("{%s,%u},%s,%u,,%llu,%u", 501 428 cookie->name.name, cookie->name.len, name, nlen, 502 429 (unsigned long long) ino, dtype); 503 430 504 431 /* insanity checks first */ 505 - BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048); 506 - BUILD_BUG_ON(sizeof(union afs_dirent) != 32); 432 + BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048); 433 + BUILD_BUG_ON(sizeof(union afs_xdr_dirent) != 32); 507 434 508 435 if (cookie->name.len != nlen || 509 436 memcmp(cookie->name.name, name, nlen) != 0) { ··· 520 447 } 521 448 522 449 /* 523 - * do a lookup in a directory 450 + * Do a lookup of a single name in a directory 524 451 * - just returns the FID the dentry name maps to if found 525 452 */ 526 - static int afs_do_lookup(struct inode *dir, struct dentry *dentry, 527 - struct afs_fid *fid, struct key *key) 453 + static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry, 454 + struct afs_fid *fid, struct key *key) 528 455 { 529 456 struct afs_super_info *as = dir->i_sb->s_fs_info; 530 - struct afs_lookup_cookie cookie = { 531 - .ctx.actor = afs_lookup_filldir, 457 + struct afs_lookup_one_cookie cookie = { 458 + .ctx.actor = afs_lookup_one_filldir, 532 459 .name = dentry->d_name, 533 460 .fid.vid = as->volume->vid 534 461 }; ··· 555 482 } 556 483 557 484 /* 558 - * Probe to see if a cell may exist. This prevents positive dentries from 559 - * being created unnecessarily. 485 + * search the directory for a name 486 + * - if afs_dir_iterate_block() spots this function, it'll pass the FID 487 + * uniquifier through dtype 560 488 */ 561 - static int afs_probe_cell_name(struct dentry *dentry) 489 + static int afs_lookup_filldir(struct dir_context *ctx, const char *name, 490 + int nlen, loff_t fpos, u64 ino, unsigned dtype) 562 491 { 563 - struct afs_cell *cell; 564 - const char *name = dentry->d_name.name; 565 - size_t len = dentry->d_name.len; 492 + struct afs_lookup_cookie *cookie = 493 + container_of(ctx, struct afs_lookup_cookie, ctx); 566 494 int ret; 567 495 568 - /* Names prefixed with a dot are R/W mounts. */ 569 - if (name[0] == '.') { 570 - if (len == 1) 571 - return -EINVAL; 572 - name++; 573 - len--; 496 + _enter("{%s,%u},%s,%u,,%llu,%u", 497 + cookie->name.name, cookie->name.len, name, nlen, 498 + (unsigned long long) ino, dtype); 499 + 500 + /* insanity checks first */ 501 + BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048); 502 + BUILD_BUG_ON(sizeof(union afs_xdr_dirent) != 32); 503 + 504 + if (cookie->found) { 505 + if (cookie->nr_fids < 50) { 506 + cookie->fids[cookie->nr_fids].vnode = ino; 507 + cookie->fids[cookie->nr_fids].unique = dtype; 508 + cookie->nr_fids++; 509 + } 510 + } else if (cookie->name.len == nlen && 511 + memcmp(cookie->name.name, name, nlen) == 0) { 512 + cookie->fids[0].vnode = ino; 513 + cookie->fids[0].unique = dtype; 514 + cookie->found = 1; 515 + if (cookie->one_only) 516 + return -1; 574 517 } 575 518 576 - cell = afs_lookup_cell_rcu(afs_d2net(dentry), name, len); 577 - if (!IS_ERR(cell)) { 578 - afs_put_cell(afs_d2net(dentry), cell); 579 - return 0; 580 - } 581 - 582 - ret = dns_query("afsdb", name, len, "ipv4", NULL, NULL); 583 - if (ret == -ENODATA) 584 - ret = -EDESTADDRREQ; 519 + ret = cookie->nr_fids >= 50 ? -1 : 0; 520 + _leave(" = %d", ret); 585 521 return ret; 586 522 } 587 523 588 524 /* 589 - * Try to auto mount the mountpoint with pseudo directory, if the autocell 590 - * operation is setted. 525 + * Do a lookup in a directory. We make use of bulk lookup to query a slew of 526 + * files in one go and create inodes for them. The inode of the file we were 527 + * asked for is returned. 591 528 */ 592 - static struct inode *afs_try_auto_mntpt(struct dentry *dentry, 593 - struct inode *dir, struct afs_fid *fid) 529 + static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, 530 + struct key *key) 594 531 { 595 - struct afs_vnode *vnode = AFS_FS_I(dir); 596 - struct inode *inode; 597 - int ret = -ENOENT; 532 + struct afs_lookup_cookie *cookie; 533 + struct afs_cb_interest *cbi = NULL; 534 + struct afs_super_info *as = dir->i_sb->s_fs_info; 535 + struct afs_iget_data data; 536 + struct afs_fs_cursor fc; 537 + struct afs_vnode *dvnode = AFS_FS_I(dir); 538 + struct inode *inode = NULL; 539 + int ret, i; 598 540 599 - _enter("%p{%pd}, {%x:%u}", 600 - dentry, dentry, vnode->fid.vid, vnode->fid.vnode); 541 + _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); 601 542 602 - if (!test_bit(AFS_VNODE_AUTOCELL, &vnode->flags)) 603 - goto out; 543 + cookie = kzalloc(sizeof(struct afs_lookup_cookie), GFP_KERNEL); 544 + if (!cookie) 545 + return ERR_PTR(-ENOMEM); 604 546 605 - ret = afs_probe_cell_name(dentry); 606 - if (ret < 0) 607 - goto out; 547 + cookie->ctx.actor = afs_lookup_filldir; 548 + cookie->name = dentry->d_name; 549 + cookie->nr_fids = 1; /* slot 0 is saved for the fid we actually want */ 608 550 609 - inode = afs_iget_pseudo_dir(dir->i_sb, false); 610 - if (IS_ERR(inode)) { 611 - ret = PTR_ERR(inode); 551 + read_seqlock_excl(&dvnode->cb_lock); 552 + if (dvnode->cb_interest && 553 + dvnode->cb_interest->server && 554 + test_bit(AFS_SERVER_FL_NO_IBULK, &dvnode->cb_interest->server->flags)) 555 + cookie->one_only = true; 556 + read_sequnlock_excl(&dvnode->cb_lock); 557 + 558 + for (i = 0; i < 50; i++) 559 + cookie->fids[i].vid = as->volume->vid; 560 + 561 + /* search the directory */ 562 + ret = afs_dir_iterate(dir, &cookie->ctx, key); 563 + if (ret < 0) { 564 + inode = ERR_PTR(ret); 612 565 goto out; 613 566 } 614 567 615 - *fid = AFS_FS_I(inode)->fid; 616 - _leave("= %p", inode); 617 - return inode; 568 + inode = ERR_PTR(-ENOENT); 569 + if (!cookie->found) 570 + goto out; 618 571 572 + /* Check to see if we already have an inode for the primary fid. */ 573 + data.volume = dvnode->volume; 574 + data.fid = cookie->fids[0]; 575 + inode = ilookup5(dir->i_sb, cookie->fids[0].vnode, afs_iget5_test, &data); 576 + if (inode) 577 + goto out; 578 + 579 + /* Need space for examining all the selected files */ 580 + inode = ERR_PTR(-ENOMEM); 581 + cookie->statuses = kcalloc(cookie->nr_fids, sizeof(struct afs_file_status), 582 + GFP_KERNEL); 583 + if (!cookie->statuses) 584 + goto out; 585 + 586 + cookie->callbacks = kcalloc(cookie->nr_fids, sizeof(struct afs_callback), 587 + GFP_KERNEL); 588 + if (!cookie->callbacks) 589 + goto out_s; 590 + 591 + /* Try FS.InlineBulkStatus first. Abort codes for the individual 592 + * lookups contained therein are stored in the reply without aborting 593 + * the whole operation. 594 + */ 595 + if (cookie->one_only) 596 + goto no_inline_bulk_status; 597 + 598 + inode = ERR_PTR(-ERESTARTSYS); 599 + if (afs_begin_vnode_operation(&fc, dvnode, key)) { 600 + while (afs_select_fileserver(&fc)) { 601 + if (test_bit(AFS_SERVER_FL_NO_IBULK, 602 + &fc.cbi->server->flags)) { 603 + fc.ac.abort_code = RX_INVALID_OPERATION; 604 + fc.ac.error = -ECONNABORTED; 605 + break; 606 + } 607 + afs_fs_inline_bulk_status(&fc, 608 + afs_v2net(dvnode), 609 + cookie->fids, 610 + cookie->statuses, 611 + cookie->callbacks, 612 + cookie->nr_fids, NULL); 613 + } 614 + 615 + if (fc.ac.error == 0) 616 + cbi = afs_get_cb_interest(fc.cbi); 617 + if (fc.ac.abort_code == RX_INVALID_OPERATION) 618 + set_bit(AFS_SERVER_FL_NO_IBULK, &fc.cbi->server->flags); 619 + inode = ERR_PTR(afs_end_vnode_operation(&fc)); 620 + } 621 + 622 + if (!IS_ERR(inode)) 623 + goto success; 624 + if (fc.ac.abort_code != RX_INVALID_OPERATION) 625 + goto out_c; 626 + 627 + no_inline_bulk_status: 628 + /* We could try FS.BulkStatus next, but this aborts the entire op if 629 + * any of the lookups fails - so, for the moment, revert to 630 + * FS.FetchStatus for just the primary fid. 631 + */ 632 + cookie->nr_fids = 1; 633 + inode = ERR_PTR(-ERESTARTSYS); 634 + if (afs_begin_vnode_operation(&fc, dvnode, key)) { 635 + while (afs_select_fileserver(&fc)) { 636 + afs_fs_fetch_status(&fc, 637 + afs_v2net(dvnode), 638 + cookie->fids, 639 + cookie->statuses, 640 + cookie->callbacks, 641 + NULL); 642 + } 643 + 644 + if (fc.ac.error == 0) 645 + cbi = afs_get_cb_interest(fc.cbi); 646 + inode = ERR_PTR(afs_end_vnode_operation(&fc)); 647 + } 648 + 649 + if (IS_ERR(inode)) 650 + goto out_c; 651 + 652 + for (i = 0; i < cookie->nr_fids; i++) 653 + cookie->statuses[i].abort_code = 0; 654 + 655 + success: 656 + /* Turn all the files into inodes and save the first one - which is the 657 + * one we actually want. 658 + */ 659 + if (cookie->statuses[0].abort_code != 0) 660 + inode = ERR_PTR(afs_abort_to_error(cookie->statuses[0].abort_code)); 661 + 662 + for (i = 0; i < cookie->nr_fids; i++) { 663 + struct inode *ti; 664 + 665 + if (cookie->statuses[i].abort_code != 0) 666 + continue; 667 + 668 + ti = afs_iget(dir->i_sb, key, &cookie->fids[i], 669 + &cookie->statuses[i], 670 + &cookie->callbacks[i], 671 + cbi); 672 + if (i == 0) { 673 + inode = ti; 674 + } else { 675 + if (!IS_ERR(ti)) 676 + iput(ti); 677 + } 678 + } 679 + 680 + out_c: 681 + afs_put_cb_interest(afs_v2net(dvnode), cbi); 682 + kfree(cookie->callbacks); 683 + out_s: 684 + kfree(cookie->statuses); 619 685 out: 620 - _leave("= %d", ret); 621 - return ERR_PTR(ret); 686 + kfree(cookie); 687 + return inode; 688 + } 689 + 690 + /* 691 + * Look up an entry in a directory with @sys substitution. 692 + */ 693 + static struct dentry *afs_lookup_atsys(struct inode *dir, struct dentry *dentry, 694 + struct key *key) 695 + { 696 + struct afs_sysnames *subs; 697 + struct afs_net *net = afs_i2net(dir); 698 + struct dentry *ret; 699 + char *buf, *p, *name; 700 + int len, i; 701 + 702 + _enter(""); 703 + 704 + ret = ERR_PTR(-ENOMEM); 705 + p = buf = kmalloc(AFSNAMEMAX, GFP_KERNEL); 706 + if (!buf) 707 + goto out_p; 708 + if (dentry->d_name.len > 4) { 709 + memcpy(p, dentry->d_name.name, dentry->d_name.len - 4); 710 + p += dentry->d_name.len - 4; 711 + } 712 + 713 + /* There is an ordered list of substitutes that we have to try. */ 714 + read_lock(&net->sysnames_lock); 715 + subs = net->sysnames; 716 + refcount_inc(&subs->usage); 717 + read_unlock(&net->sysnames_lock); 718 + 719 + for (i = 0; i < subs->nr; i++) { 720 + name = subs->subs[i]; 721 + len = dentry->d_name.len - 4 + strlen(name); 722 + if (len >= AFSNAMEMAX) { 723 + ret = ERR_PTR(-ENAMETOOLONG); 724 + goto out_s; 725 + } 726 + 727 + strcpy(p, name); 728 + ret = lookup_one_len(buf, dentry->d_parent, len); 729 + if (IS_ERR(ret) || d_is_positive(ret)) 730 + goto out_s; 731 + dput(ret); 732 + } 733 + 734 + /* We don't want to d_add() the @sys dentry here as we don't want to 735 + * the cached dentry to hide changes to the sysnames list. 736 + */ 737 + ret = NULL; 738 + out_s: 739 + afs_put_sysnames(subs); 740 + kfree(buf); 741 + out_p: 742 + key_put(key); 743 + return ret; 622 744 } 623 745 624 746 /* ··· 822 554 static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, 823 555 unsigned int flags) 824 556 { 825 - struct afs_vnode *vnode; 826 - struct afs_fid fid; 557 + struct afs_vnode *dvnode = AFS_FS_I(dir); 827 558 struct inode *inode; 828 559 struct key *key; 829 560 int ret; 830 561 831 - vnode = AFS_FS_I(dir); 832 - 833 562 _enter("{%x:%u},%p{%pd},", 834 - vnode->fid.vid, vnode->fid.vnode, dentry, dentry); 563 + dvnode->fid.vid, dvnode->fid.vnode, dentry, dentry); 835 564 836 565 ASSERTCMP(d_inode(dentry), ==, NULL); 837 566 ··· 837 572 return ERR_PTR(-ENAMETOOLONG); 838 573 } 839 574 840 - if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) { 575 + if (test_bit(AFS_VNODE_DELETED, &dvnode->flags)) { 841 576 _leave(" = -ESTALE"); 842 577 return ERR_PTR(-ESTALE); 843 578 } 844 579 845 - key = afs_request_key(vnode->volume->cell); 580 + key = afs_request_key(dvnode->volume->cell); 846 581 if (IS_ERR(key)) { 847 582 _leave(" = %ld [key]", PTR_ERR(key)); 848 583 return ERR_CAST(key); 849 584 } 850 585 851 - ret = afs_validate(vnode, key); 586 + ret = afs_validate(dvnode, key); 852 587 if (ret < 0) { 853 588 key_put(key); 854 589 _leave(" = %d [val]", ret); 855 590 return ERR_PTR(ret); 856 591 } 857 592 858 - ret = afs_do_lookup(dir, dentry, &fid, key); 859 - if (ret < 0) { 593 + if (dentry->d_name.len >= 4 && 594 + dentry->d_name.name[dentry->d_name.len - 4] == '@' && 595 + dentry->d_name.name[dentry->d_name.len - 3] == 's' && 596 + dentry->d_name.name[dentry->d_name.len - 2] == 'y' && 597 + dentry->d_name.name[dentry->d_name.len - 1] == 's') 598 + return afs_lookup_atsys(dir, dentry, key); 599 + 600 + afs_stat_v(dvnode, n_lookup); 601 + inode = afs_do_lookup(dir, dentry, key); 602 + if (IS_ERR(inode)) { 603 + ret = PTR_ERR(inode); 860 604 if (ret == -ENOENT) { 861 - inode = afs_try_auto_mntpt(dentry, dir, &fid); 605 + inode = afs_try_auto_mntpt(dentry, dir); 862 606 if (!IS_ERR(inode)) { 863 607 key_put(key); 864 608 goto success; ··· 885 611 _leave(" = %d [do]", ret); 886 612 return ERR_PTR(ret); 887 613 } 888 - dentry->d_fsdata = (void *)(unsigned long) vnode->status.data_version; 614 + dentry->d_fsdata = (void *)(unsigned long)dvnode->status.data_version; 889 615 890 616 /* instantiate the dentry */ 891 - inode = afs_iget(dir->i_sb, key, &fid, NULL, NULL, NULL); 892 617 key_put(key); 893 618 if (IS_ERR(inode)) { 894 619 _leave(" = %ld", PTR_ERR(inode)); ··· 896 623 897 624 success: 898 625 d_add(dentry, inode); 899 - _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%u }", 900 - fid.vnode, 901 - fid.unique, 626 + _leave(" = 0 { ino=%lu v=%u }", 902 627 d_inode(dentry)->i_ino, 903 628 d_inode(dentry)->i_generation); 904 629 905 - return NULL; 906 - } 907 - 908 - /* 909 - * Look up an entry in a dynroot directory. 910 - */ 911 - static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry, 912 - unsigned int flags) 913 - { 914 - struct afs_vnode *vnode; 915 - struct afs_fid fid; 916 - struct inode *inode; 917 - int ret; 918 - 919 - vnode = AFS_FS_I(dir); 920 - 921 - _enter("%pd", dentry); 922 - 923 - ASSERTCMP(d_inode(dentry), ==, NULL); 924 - 925 - if (dentry->d_name.len >= AFSNAMEMAX) { 926 - _leave(" = -ENAMETOOLONG"); 927 - return ERR_PTR(-ENAMETOOLONG); 928 - } 929 - 930 - inode = afs_try_auto_mntpt(dentry, dir, &fid); 931 - if (IS_ERR(inode)) { 932 - ret = PTR_ERR(inode); 933 - if (ret == -ENOENT) { 934 - d_add(dentry, NULL); 935 - _leave(" = NULL [negative]"); 936 - return NULL; 937 - } 938 - _leave(" = %d [do]", ret); 939 - return ERR_PTR(ret); 940 - } 941 - 942 - d_add(dentry, inode); 943 - _leave(" = 0 { ino=%lu v=%u }", 944 - d_inode(dentry)->i_ino, d_inode(dentry)->i_generation); 945 630 return NULL; 946 631 } 947 632 ··· 910 679 */ 911 680 static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) 912 681 { 913 - struct afs_super_info *as = dentry->d_sb->s_fs_info; 914 682 struct afs_vnode *vnode, *dir; 915 683 struct afs_fid uninitialized_var(fid); 916 684 struct dentry *parent; 917 685 struct inode *inode; 918 686 struct key *key; 919 - void *dir_version; 687 + long dir_version, de_version; 920 688 int ret; 921 689 922 690 if (flags & LOOKUP_RCU) 923 691 return -ECHILD; 924 - 925 - if (as->dyn_root) 926 - return 1; 927 692 928 693 if (d_really_is_positive(dentry)) { 929 694 vnode = AFS_FS_I(d_inode(dentry)); ··· 956 729 goto out_bad_parent; 957 730 } 958 731 959 - dir_version = (void *) (unsigned long) dir->status.data_version; 960 - if (dentry->d_fsdata == dir_version) 961 - goto out_valid; /* the dir contents are unchanged */ 732 + /* We only need to invalidate a dentry if the server's copy changed 733 + * behind our back. If we made the change, it's no problem. Note that 734 + * on a 32-bit system, we only have 32 bits in the dentry to store the 735 + * version. 736 + */ 737 + dir_version = (long)dir->status.data_version; 738 + de_version = (long)dentry->d_fsdata; 739 + if (de_version == dir_version) 740 + goto out_valid; 741 + 742 + dir_version = (long)dir->invalid_before; 743 + if (de_version - dir_version >= 0) 744 + goto out_valid; 962 745 963 746 _debug("dir modified"); 747 + afs_stat_v(dir, n_reval); 964 748 965 749 /* search the directory for this vnode */ 966 - ret = afs_do_lookup(&dir->vfs_inode, dentry, &fid, key); 750 + ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key); 967 751 switch (ret) { 968 752 case 0: 969 753 /* the filename maps to something */ ··· 1027 789 } 1028 790 1029 791 out_valid: 1030 - dentry->d_fsdata = dir_version; 792 + dentry->d_fsdata = (void *)dir_version; 1031 793 dput(parent); 1032 794 key_put(key); 1033 795 _leave(" = 1 [valid]"); ··· 1078 840 /* 1079 841 * handle dentry release 1080 842 */ 1081 - static void afs_d_release(struct dentry *dentry) 843 + void afs_d_release(struct dentry *dentry) 1082 844 { 1083 845 _enter("%pd", dentry); 1084 846 } ··· 1092 854 struct afs_file_status *newstatus, 1093 855 struct afs_callback *newcb) 1094 856 { 857 + struct afs_vnode *vnode; 1095 858 struct inode *inode; 1096 859 1097 860 if (fc->ac.error < 0) ··· 1110 871 return; 1111 872 } 1112 873 874 + vnode = AFS_FS_I(inode); 875 + set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 1113 876 d_add(new_dentry, inode); 1114 877 } 1115 878 ··· 1126 885 struct afs_vnode *dvnode = AFS_FS_I(dir); 1127 886 struct afs_fid newfid; 1128 887 struct key *key; 888 + u64 data_version = dvnode->status.data_version; 1129 889 int ret; 1130 890 1131 891 mode |= S_IFDIR; ··· 1144 902 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1145 903 while (afs_select_fileserver(&fc)) { 1146 904 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1147 - afs_fs_create(&fc, dentry->d_name.name, mode, 905 + afs_fs_create(&fc, dentry->d_name.name, mode, data_version, 1148 906 &newfid, &newstatus, &newcb); 1149 907 } 1150 908 ··· 1157 915 } else { 1158 916 goto error_key; 1159 917 } 918 + 919 + if (ret == 0 && 920 + test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 921 + afs_edit_dir_add(dvnode, &dentry->d_name, &newfid, 922 + afs_edit_dir_for_create); 1160 923 1161 924 key_put(key); 1162 925 _leave(" = 0"); ··· 1186 939 clear_nlink(&vnode->vfs_inode); 1187 940 set_bit(AFS_VNODE_DELETED, &vnode->flags); 1188 941 clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); 942 + clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags); 1189 943 } 1190 944 } 1191 945 ··· 1198 950 struct afs_fs_cursor fc; 1199 951 struct afs_vnode *dvnode = AFS_FS_I(dir); 1200 952 struct key *key; 953 + u64 data_version = dvnode->status.data_version; 1201 954 int ret; 1202 955 1203 956 _enter("{%x:%u},{%pd}", ··· 1214 965 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1215 966 while (afs_select_fileserver(&fc)) { 1216 967 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1217 - afs_fs_remove(&fc, dentry->d_name.name, true); 968 + afs_fs_remove(&fc, dentry->d_name.name, true, 969 + data_version); 1218 970 } 1219 971 1220 972 afs_vnode_commit_status(&fc, dvnode, fc.cb_break); 1221 973 ret = afs_end_vnode_operation(&fc); 1222 - if (ret == 0) 974 + if (ret == 0) { 1223 975 afs_dir_remove_subdir(dentry); 976 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 977 + afs_edit_dir_remove(dvnode, &dentry->d_name, 978 + afs_edit_dir_for_rmdir); 979 + } 1224 980 } 1225 981 1226 982 key_put(key); ··· 1290 1036 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode; 1291 1037 struct key *key; 1292 1038 unsigned long d_version = (unsigned long)dentry->d_fsdata; 1039 + u64 data_version = dvnode->status.data_version; 1293 1040 int ret; 1294 1041 1295 1042 _enter("{%x:%u},{%pd}", ··· 1317 1062 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1318 1063 while (afs_select_fileserver(&fc)) { 1319 1064 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1320 - afs_fs_remove(&fc, dentry->d_name.name, false); 1065 + afs_fs_remove(&fc, dentry->d_name.name, false, 1066 + data_version); 1321 1067 } 1322 1068 1323 1069 afs_vnode_commit_status(&fc, dvnode, fc.cb_break); ··· 1327 1071 ret = afs_dir_remove_link( 1328 1072 dentry, key, d_version, 1329 1073 (unsigned long)dvnode->status.data_version); 1074 + if (ret == 0 && 1075 + test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 1076 + afs_edit_dir_remove(dvnode, &dentry->d_name, 1077 + afs_edit_dir_for_unlink); 1330 1078 } 1331 1079 1332 1080 error_key: ··· 1352 1092 struct afs_vnode *dvnode = AFS_FS_I(dir); 1353 1093 struct afs_fid newfid; 1354 1094 struct key *key; 1095 + u64 data_version = dvnode->status.data_version; 1355 1096 int ret; 1356 1097 1357 1098 mode |= S_IFREG; ··· 1374 1113 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1375 1114 while (afs_select_fileserver(&fc)) { 1376 1115 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1377 - afs_fs_create(&fc, dentry->d_name.name, mode, 1116 + afs_fs_create(&fc, dentry->d_name.name, mode, data_version, 1378 1117 &newfid, &newstatus, &newcb); 1379 1118 } 1380 1119 ··· 1387 1126 } else { 1388 1127 goto error_key; 1389 1128 } 1129 + 1130 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 1131 + afs_edit_dir_add(dvnode, &dentry->d_name, &newfid, 1132 + afs_edit_dir_for_create); 1390 1133 1391 1134 key_put(key); 1392 1135 _leave(" = 0"); ··· 1413 1148 struct afs_fs_cursor fc; 1414 1149 struct afs_vnode *dvnode, *vnode; 1415 1150 struct key *key; 1151 + u64 data_version; 1416 1152 int ret; 1417 1153 1418 1154 vnode = AFS_FS_I(d_inode(from)); 1419 1155 dvnode = AFS_FS_I(dir); 1156 + data_version = dvnode->status.data_version; 1420 1157 1421 1158 _enter("{%x:%u},{%x:%u},{%pd}", 1422 1159 vnode->fid.vid, vnode->fid.vnode, ··· 1445 1178 while (afs_select_fileserver(&fc)) { 1446 1179 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1447 1180 fc.cb_break_2 = vnode->cb_break + vnode->cb_s_break; 1448 - afs_fs_link(&fc, vnode, dentry->d_name.name); 1181 + afs_fs_link(&fc, vnode, dentry->d_name.name, data_version); 1449 1182 } 1450 1183 1451 1184 afs_vnode_commit_status(&fc, dvnode, fc.cb_break); ··· 1460 1193 } else { 1461 1194 goto error_key; 1462 1195 } 1196 + 1197 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 1198 + afs_edit_dir_add(dvnode, &dentry->d_name, &vnode->fid, 1199 + afs_edit_dir_for_link); 1463 1200 1464 1201 key_put(key); 1465 1202 _leave(" = 0"); ··· 1488 1217 struct afs_vnode *dvnode = AFS_FS_I(dir); 1489 1218 struct afs_fid newfid; 1490 1219 struct key *key; 1220 + u64 data_version = dvnode->status.data_version; 1491 1221 int ret; 1492 1222 1493 1223 _enter("{%x:%u},{%pd},%s", ··· 1513 1241 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1514 1242 while (afs_select_fileserver(&fc)) { 1515 1243 fc.cb_break = dvnode->cb_break + dvnode->cb_s_break; 1516 - afs_fs_symlink(&fc, dentry->d_name.name, content, 1244 + afs_fs_symlink(&fc, dentry->d_name.name, 1245 + content, data_version, 1517 1246 &newfid, &newstatus); 1518 1247 } 1519 1248 ··· 1527 1254 } else { 1528 1255 goto error_key; 1529 1256 } 1257 + 1258 + if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 1259 + afs_edit_dir_add(dvnode, &dentry->d_name, &newfid, 1260 + afs_edit_dir_for_symlink); 1530 1261 1531 1262 key_put(key); 1532 1263 _leave(" = 0"); ··· 1554 1277 struct afs_fs_cursor fc; 1555 1278 struct afs_vnode *orig_dvnode, *new_dvnode, *vnode; 1556 1279 struct key *key; 1280 + u64 orig_data_version, new_data_version; 1281 + bool new_negative = d_is_negative(new_dentry); 1557 1282 int ret; 1558 1283 1559 1284 if (flags) ··· 1564 1285 vnode = AFS_FS_I(d_inode(old_dentry)); 1565 1286 orig_dvnode = AFS_FS_I(old_dir); 1566 1287 new_dvnode = AFS_FS_I(new_dir); 1288 + orig_data_version = orig_dvnode->status.data_version; 1289 + new_data_version = new_dvnode->status.data_version; 1567 1290 1568 1291 _enter("{%x:%u},{%x:%u},{%x:%u},{%pd}", 1569 1292 orig_dvnode->fid.vid, orig_dvnode->fid.vnode, ··· 1591 1310 fc.cb_break = orig_dvnode->cb_break + orig_dvnode->cb_s_break; 1592 1311 fc.cb_break_2 = new_dvnode->cb_break + new_dvnode->cb_s_break; 1593 1312 afs_fs_rename(&fc, old_dentry->d_name.name, 1594 - new_dvnode, new_dentry->d_name.name); 1313 + new_dvnode, new_dentry->d_name.name, 1314 + orig_data_version, new_data_version); 1595 1315 } 1596 1316 1597 1317 afs_vnode_commit_status(&fc, orig_dvnode, fc.cb_break); ··· 1604 1322 goto error_key; 1605 1323 } 1606 1324 1325 + if (ret == 0) { 1326 + if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags)) 1327 + afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name, 1328 + afs_edit_dir_for_rename); 1329 + 1330 + if (!new_negative && 1331 + test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) 1332 + afs_edit_dir_remove(new_dvnode, &new_dentry->d_name, 1333 + afs_edit_dir_for_rename); 1334 + 1335 + if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags)) 1336 + afs_edit_dir_add(new_dvnode, &new_dentry->d_name, 1337 + &vnode->fid, afs_edit_dir_for_rename); 1338 + } 1339 + 1607 1340 error_key: 1608 1341 key_put(key); 1609 1342 error: 1610 1343 _leave(" = %d", ret); 1611 1344 return ret; 1345 + } 1346 + 1347 + /* 1348 + * Release a directory page and clean up its private state if it's not busy 1349 + * - return true if the page can now be released, false if not 1350 + */ 1351 + static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags) 1352 + { 1353 + struct afs_vnode *dvnode = AFS_FS_I(page->mapping->host); 1354 + 1355 + _enter("{{%x:%u}[%lu]}", dvnode->fid.vid, dvnode->fid.vnode, page->index); 1356 + 1357 + set_page_private(page, 0); 1358 + ClearPagePrivate(page); 1359 + 1360 + /* The directory will need reloading. */ 1361 + if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 1362 + afs_stat_v(dvnode, n_relpg); 1363 + return 1; 1364 + } 1365 + 1366 + /* 1367 + * invalidate part or all of a page 1368 + * - release a page and clean up its private data if offset is 0 (indicating 1369 + * the entire page) 1370 + */ 1371 + static void afs_dir_invalidatepage(struct page *page, unsigned int offset, 1372 + unsigned int length) 1373 + { 1374 + struct afs_vnode *dvnode = AFS_FS_I(page->mapping->host); 1375 + 1376 + _enter("{%lu},%u,%u", page->index, offset, length); 1377 + 1378 + BUG_ON(!PageLocked(page)); 1379 + 1380 + /* The directory will need reloading. */ 1381 + if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) 1382 + afs_stat_v(dvnode, n_inval); 1383 + 1384 + /* we clean up only if the entire page is being invalidated */ 1385 + if (offset == 0 && length == PAGE_SIZE) { 1386 + set_page_private(page, 0); 1387 + ClearPagePrivate(page); 1388 + } 1612 1389 }
+505
fs/afs/dir_edit.c
··· 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 + */ 27 + static 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 + */ 72 + static 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 + */ 97 + static 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 + */ 122 + static 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 + */ 167 + static 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 + */ 198 + void 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 + 311 + new_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 + 321 + found_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 + 350 + out_unmap: 351 + unlock_page(page0); 352 + kunmap(page0); 353 + put_page(page0); 354 + _leave(""); 355 + return; 356 + 357 + invalidated: 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 + 366 + error: 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 + */ 379 + void 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 + 457 + found_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 + 482 + out_unmap: 483 + unlock_page(page0); 484 + kunmap(page0); 485 + put_page(page0); 486 + _leave(""); 487 + return; 488 + 489 + invalidated: 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 + 500 + error: 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 + }
+209
fs/afs/dynroot.c
··· 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 + 17 + const 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 + */ 28 + static 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 + */ 59 + struct 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 + 84 + out: 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 + */ 93 + static 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 + 132 + out_n: 133 + kfree(name); 134 + out_p: 135 + return ret; 136 + } 137 + 138 + /* 139 + * Look up an entry in a dynroot directory. 140 + */ 141 + static 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 + 181 + const 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 + */ 188 + static 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 + */ 199 + static int afs_dynroot_d_delete(const struct dentry *dentry) 200 + { 201 + return d_really_is_positive(dentry); 202 + } 203 + 204 + const 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 + };
+19 -8
fs/afs/file.c
··· 30 30 31 31 const struct file_operations afs_file_operations = { 32 32 .open = afs_open, 33 - .flush = afs_flush, 34 33 .release = afs_release, 35 34 .llseek = generic_file_llseek, 36 35 .read_iter = generic_file_read_iter, ··· 145 146 if (ret < 0) 146 147 goto error_af; 147 148 } 149 + 150 + if (file->f_flags & O_TRUNC) 151 + set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 148 152 149 153 file->private_data = af; 150 154 _leave(" = 0"); ··· 172 170 173 171 _enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode); 174 172 173 + if ((file->f_mode & FMODE_WRITE)) 174 + return vfs_fsync(file, 0); 175 + 175 176 file->private_data = NULL; 176 177 if (af->wb) 177 178 afs_put_wb_key(af->wb); ··· 192 187 { 193 188 int i; 194 189 195 - if (atomic_dec_and_test(&req->usage)) { 190 + if (refcount_dec_and_test(&req->usage)) { 196 191 for (i = 0; i < req->nr_pages; i++) 197 192 if (req->pages[i]) 198 193 put_page(req->pages[i]); 194 + if (req->pages != req->array) 195 + kfree(req->pages); 199 196 kfree(req); 200 197 } 201 198 } ··· 245 238 afs_check_for_remote_deletion(&fc, fc.vnode); 246 239 afs_vnode_commit_status(&fc, vnode, fc.cb_break); 247 240 ret = afs_end_vnode_operation(&fc); 241 + } 242 + 243 + if (ret == 0) { 244 + afs_stat_v(vnode, n_fetches); 245 + atomic_long_add(desc->actual_len, 246 + &afs_v2net(vnode)->n_fetch_bytes); 248 247 } 249 248 250 249 _leave(" = %d", ret); ··· 310 297 * end of the file, the server will return a short read and the 311 298 * unmarshalling code will clear the unfilled space. 312 299 */ 313 - atomic_set(&req->usage, 1); 300 + refcount_set(&req->usage, 1); 314 301 req->pos = (loff_t)page->index << PAGE_SHIFT; 315 302 req->len = PAGE_SIZE; 316 303 req->nr_pages = 1; 304 + req->pages = req->array; 317 305 req->pages[0] = page; 318 306 get_page(page); 319 307 ··· 322 308 * page */ 323 309 ret = afs_fetch_data(vnode, key, req); 324 310 afs_put_read(req); 325 - 326 - if (ret >= 0 && S_ISDIR(inode->i_mode) && 327 - !afs_dir_check_page(inode, page)) 328 - ret = -EIO; 329 311 330 312 if (ret < 0) { 331 313 if (ret == -ENOENT) { ··· 457 447 if (!req) 458 448 return -ENOMEM; 459 449 460 - atomic_set(&req->usage, 1); 450 + refcount_set(&req->usage, 1); 461 451 req->page_done = afs_readpages_page_done; 462 452 req->pos = first->index; 463 453 req->pos <<= PAGE_SHIFT; 454 + req->pages = req->array; 464 455 465 456 /* Transfer the pages to the request. We add them in until one fails 466 457 * to add to the LRU and then we stop (as that'll make a hole in the
+1 -1
fs/afs/flock.c
··· 613 613 posix_test_lock(file, fl); 614 614 if (fl->fl_type == F_UNLCK) { 615 615 /* no local locks; consult the server */ 616 - ret = afs_fetch_status(vnode, key); 616 + ret = afs_fetch_status(vnode, key, false); 617 617 if (ret < 0) 618 618 goto error; 619 619
+500 -122
fs/afs/fsclient.c
··· 16 16 #include <linux/iversion.h> 17 17 #include "internal.h" 18 18 #include "afs_fs.h" 19 + #include "xdr_fs.h" 19 20 20 21 static const struct afs_fid afs_zero_fid; 21 22 ··· 45 44 } 46 45 47 46 /* 47 + * Dump a bad file status record. 48 + */ 49 + static void xdr_dump_bad(const __be32 *bp) 50 + { 51 + __be32 x[4]; 52 + int i; 53 + 54 + pr_notice("AFS XDR: Bad status record\n"); 55 + for (i = 0; i < 5 * 4 * 4; i += 16) { 56 + memcpy(x, bp, 16); 57 + bp += 4; 58 + pr_notice("%03x: %08x %08x %08x %08x\n", 59 + i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3])); 60 + } 61 + 62 + memcpy(x, bp, 4); 63 + pr_notice("0x50: %08x\n", ntohl(x[0])); 64 + } 65 + 66 + /* 67 + * Update the core inode struct from a returned status record. 68 + */ 69 + void afs_update_inode_from_status(struct afs_vnode *vnode, 70 + struct afs_file_status *status, 71 + const afs_dataversion_t *expected_version, 72 + u8 flags) 73 + { 74 + struct timespec t; 75 + umode_t mode; 76 + 77 + t.tv_sec = status->mtime_client; 78 + t.tv_nsec = 0; 79 + vnode->vfs_inode.i_ctime = t; 80 + vnode->vfs_inode.i_mtime = t; 81 + vnode->vfs_inode.i_atime = t; 82 + 83 + if (flags & (AFS_VNODE_META_CHANGED | AFS_VNODE_NOT_YET_SET)) { 84 + vnode->vfs_inode.i_uid = make_kuid(&init_user_ns, status->owner); 85 + vnode->vfs_inode.i_gid = make_kgid(&init_user_ns, status->group); 86 + set_nlink(&vnode->vfs_inode, status->nlink); 87 + 88 + mode = vnode->vfs_inode.i_mode; 89 + mode &= ~S_IALLUGO; 90 + mode |= status->mode; 91 + barrier(); 92 + vnode->vfs_inode.i_mode = mode; 93 + } 94 + 95 + if (!(flags & AFS_VNODE_NOT_YET_SET)) { 96 + if (expected_version && 97 + *expected_version != status->data_version) { 98 + _debug("vnode modified %llx on {%x:%u} [exp %llx]", 99 + (unsigned long long) status->data_version, 100 + vnode->fid.vid, vnode->fid.vnode, 101 + (unsigned long long) *expected_version); 102 + vnode->invalid_before = status->data_version; 103 + if (vnode->status.type == AFS_FTYPE_DIR) { 104 + if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags)) 105 + afs_stat_v(vnode, n_inval); 106 + } else { 107 + set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags); 108 + } 109 + } else if (vnode->status.type == AFS_FTYPE_DIR) { 110 + /* Expected directory change is handled elsewhere so 111 + * that we can locally edit the directory and save on a 112 + * download. 113 + */ 114 + if (test_bit(AFS_VNODE_DIR_VALID, &vnode->flags)) 115 + flags &= ~AFS_VNODE_DATA_CHANGED; 116 + } 117 + } 118 + 119 + if (flags & (AFS_VNODE_DATA_CHANGED | AFS_VNODE_NOT_YET_SET)) { 120 + inode_set_iversion_raw(&vnode->vfs_inode, status->data_version); 121 + i_size_write(&vnode->vfs_inode, status->size); 122 + } 123 + } 124 + 125 + /* 48 126 * decode an AFSFetchStatus block 49 127 */ 50 - static void xdr_decode_AFSFetchStatus(const __be32 **_bp, 51 - struct afs_file_status *status, 52 - struct afs_vnode *vnode, 53 - afs_dataversion_t *store_version) 128 + static int xdr_decode_AFSFetchStatus(struct afs_call *call, 129 + const __be32 **_bp, 130 + struct afs_file_status *status, 131 + struct afs_vnode *vnode, 132 + const afs_dataversion_t *expected_version, 133 + struct afs_read *read_req) 54 134 { 55 - afs_dataversion_t expected_version; 56 - const __be32 *bp = *_bp; 57 - umode_t mode; 135 + const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp; 58 136 u64 data_version, size; 59 - bool changed = false; 60 - kuid_t owner; 61 - kgid_t group; 137 + u32 type, abort_code; 138 + u8 flags = 0; 139 + int ret; 62 140 63 141 if (vnode) 64 142 write_seqlock(&vnode->cb_lock); 65 143 66 - #define EXTRACT(DST) \ 67 - do { \ 68 - u32 x = ntohl(*bp++); \ 69 - if (DST != x) \ 70 - changed |= true; \ 71 - DST = x; \ 144 + if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) { 145 + pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); 146 + goto bad; 147 + } 148 + 149 + type = ntohl(xdr->type); 150 + abort_code = ntohl(xdr->abort_code); 151 + switch (type) { 152 + case AFS_FTYPE_FILE: 153 + case AFS_FTYPE_DIR: 154 + case AFS_FTYPE_SYMLINK: 155 + if (type != status->type && 156 + vnode && 157 + !test_bit(AFS_VNODE_UNSET, &vnode->flags)) { 158 + pr_warning("Vnode %x:%x:%x changed type %u to %u\n", 159 + vnode->fid.vid, 160 + vnode->fid.vnode, 161 + vnode->fid.unique, 162 + status->type, type); 163 + goto bad; 164 + } 165 + status->type = type; 166 + break; 167 + case AFS_FTYPE_INVALID: 168 + if (abort_code != 0) { 169 + status->abort_code = abort_code; 170 + ret = 0; 171 + goto out; 172 + } 173 + /* Fall through */ 174 + default: 175 + goto bad; 176 + } 177 + 178 + #define EXTRACT_M(FIELD) \ 179 + do { \ 180 + u32 x = ntohl(xdr->FIELD); \ 181 + if (status->FIELD != x) { \ 182 + flags |= AFS_VNODE_META_CHANGED; \ 183 + status->FIELD = x; \ 184 + } \ 72 185 } while (0) 73 186 74 - status->if_version = ntohl(*bp++); 75 - EXTRACT(status->type); 76 - EXTRACT(status->nlink); 77 - size = ntohl(*bp++); 78 - data_version = ntohl(*bp++); 79 - EXTRACT(status->author); 80 - owner = make_kuid(&init_user_ns, ntohl(*bp++)); 81 - changed |= !uid_eq(owner, status->owner); 82 - status->owner = owner; 83 - EXTRACT(status->caller_access); /* call ticket dependent */ 84 - EXTRACT(status->anon_access); 85 - EXTRACT(status->mode); 86 - bp++; /* parent.vnode */ 87 - bp++; /* parent.unique */ 88 - bp++; /* seg size */ 89 - status->mtime_client = ntohl(*bp++); 90 - status->mtime_server = ntohl(*bp++); 91 - group = make_kgid(&init_user_ns, ntohl(*bp++)); 92 - changed |= !gid_eq(group, status->group); 93 - status->group = group; 94 - bp++; /* sync counter */ 95 - data_version |= (u64) ntohl(*bp++) << 32; 96 - EXTRACT(status->lock_count); 97 - size |= (u64) ntohl(*bp++) << 32; 98 - bp++; /* spare 4 */ 99 - *_bp = bp; 187 + EXTRACT_M(nlink); 188 + EXTRACT_M(author); 189 + EXTRACT_M(owner); 190 + EXTRACT_M(caller_access); /* call ticket dependent */ 191 + EXTRACT_M(anon_access); 192 + EXTRACT_M(mode); 193 + EXTRACT_M(group); 100 194 101 - if (size != status->size) { 102 - status->size = size; 103 - changed |= true; 195 + status->mtime_client = ntohl(xdr->mtime_client); 196 + status->mtime_server = ntohl(xdr->mtime_server); 197 + status->lock_count = ntohl(xdr->lock_count); 198 + 199 + size = (u64)ntohl(xdr->size_lo); 200 + size |= (u64)ntohl(xdr->size_hi) << 32; 201 + status->size = size; 202 + 203 + data_version = (u64)ntohl(xdr->data_version_lo); 204 + data_version |= (u64)ntohl(xdr->data_version_hi) << 32; 205 + if (data_version != status->data_version) { 206 + status->data_version = data_version; 207 + flags |= AFS_VNODE_DATA_CHANGED; 104 208 } 105 - status->mode &= S_IALLUGO; 106 209 107 - _debug("vnode time %lx, %lx", 108 - status->mtime_client, status->mtime_server); 210 + if (read_req) { 211 + read_req->data_version = data_version; 212 + read_req->file_size = size; 213 + } 214 + 215 + *_bp = (const void *)*_bp + sizeof(*xdr); 109 216 110 217 if (vnode) { 111 - if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) { 112 - _debug("vnode changed"); 113 - i_size_write(&vnode->vfs_inode, size); 114 - vnode->vfs_inode.i_uid = status->owner; 115 - vnode->vfs_inode.i_gid = status->group; 116 - vnode->vfs_inode.i_generation = vnode->fid.unique; 117 - set_nlink(&vnode->vfs_inode, status->nlink); 118 - 119 - mode = vnode->vfs_inode.i_mode; 120 - mode &= ~S_IALLUGO; 121 - mode |= status->mode; 122 - barrier(); 123 - vnode->vfs_inode.i_mode = mode; 124 - } 125 - 126 - vnode->vfs_inode.i_ctime.tv_sec = status->mtime_client; 127 - vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime; 128 - vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime; 129 - inode_set_iversion_raw(&vnode->vfs_inode, data_version); 218 + if (test_bit(AFS_VNODE_UNSET, &vnode->flags)) 219 + flags |= AFS_VNODE_NOT_YET_SET; 220 + afs_update_inode_from_status(vnode, status, expected_version, 221 + flags); 130 222 } 131 223 132 - expected_version = status->data_version; 133 - if (store_version) 134 - expected_version = *store_version; 224 + ret = 0; 135 225 136 - if (expected_version != data_version) { 137 - status->data_version = data_version; 138 - if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) { 139 - _debug("vnode modified %llx on {%x:%u}", 140 - (unsigned long long) data_version, 141 - vnode->fid.vid, vnode->fid.vnode); 142 - set_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags); 143 - set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags); 144 - } 145 - } else if (store_version) { 146 - status->data_version = data_version; 147 - } 148 - 226 + out: 149 227 if (vnode) 150 228 write_sequnlock(&vnode->cb_lock); 229 + return ret; 230 + 231 + bad: 232 + xdr_dump_bad(*_bp); 233 + ret = afs_protocol_error(call, -EBADMSG); 234 + goto out; 151 235 } 152 236 153 237 /* ··· 360 274 /* 361 275 * deliver reply data to an FS.FetchStatus 362 276 */ 363 - static int afs_deliver_fs_fetch_status(struct afs_call *call) 277 + static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call) 364 278 { 365 279 struct afs_vnode *vnode = call->reply[0]; 366 280 const __be32 *bp; ··· 374 288 375 289 /* unmarshall the reply once we've received all of it */ 376 290 bp = call->buffer; 377 - xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 291 + if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 292 + &call->expected_version, NULL) < 0) 293 + return afs_protocol_error(call, -EBADMSG); 378 294 xdr_decode_AFSCallBack(call, vnode, &bp); 379 295 if (call->reply[1]) 380 296 xdr_decode_AFSVolSync(&bp, call->reply[1]); ··· 388 300 /* 389 301 * FS.FetchStatus operation type 390 302 */ 391 - static const struct afs_call_type afs_RXFSFetchStatus = { 392 - .name = "FS.FetchStatus", 303 + static const struct afs_call_type afs_RXFSFetchStatus_vnode = { 304 + .name = "FS.FetchStatus(vnode)", 393 305 .op = afs_FS_FetchStatus, 394 - .deliver = afs_deliver_fs_fetch_status, 306 + .deliver = afs_deliver_fs_fetch_status_vnode, 395 307 .destructor = afs_flat_call_destructor, 396 308 }; 397 309 398 310 /* 399 311 * fetch the status information for a file 400 312 */ 401 - int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync) 313 + int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync, 314 + bool new_inode) 402 315 { 403 316 struct afs_vnode *vnode = fc->vnode; 404 317 struct afs_call *call; ··· 409 320 _enter(",%x,{%x:%u},,", 410 321 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 411 322 412 - call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4); 323 + call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus_vnode, 324 + 16, (21 + 3 + 6) * 4); 413 325 if (!call) { 414 326 fc->ac.error = -ENOMEM; 415 327 return -ENOMEM; ··· 419 329 call->key = fc->key; 420 330 call->reply[0] = vnode; 421 331 call->reply[1] = volsync; 332 + call->expected_version = new_inode ? 1 : vnode->status.data_version; 422 333 423 334 /* marshall the parameters */ 424 335 bp = call->request; ··· 555 464 return ret; 556 465 557 466 bp = call->buffer; 558 - xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 467 + if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 468 + &vnode->status.data_version, req) < 0) 469 + return afs_protocol_error(call, -EBADMSG); 559 470 xdr_decode_AFSCallBack(call, vnode, &bp); 560 471 if (call->reply[1]) 561 472 xdr_decode_AFSVolSync(&bp, call->reply[1]); ··· 627 534 call->reply[0] = vnode; 628 535 call->reply[1] = NULL; /* volsync */ 629 536 call->reply[2] = req; 537 + call->expected_version = vnode->status.data_version; 630 538 631 539 /* marshall the parameters */ 632 540 bp = call->request; ··· 640 546 bp[6] = 0; 641 547 bp[7] = htonl(lower_32_bits(req->len)); 642 548 643 - atomic_inc(&req->usage); 549 + refcount_inc(&req->usage); 644 550 call->cb_break = fc->cb_break; 645 551 afs_use_fs_server(call, fc->cbi); 646 552 trace_afs_make_fs_call(call, &vnode->fid); ··· 672 578 call->reply[0] = vnode; 673 579 call->reply[1] = NULL; /* volsync */ 674 580 call->reply[2] = req; 581 + call->expected_version = vnode->status.data_version; 675 582 676 583 /* marshall the parameters */ 677 584 bp = call->request; ··· 683 588 bp[4] = htonl(lower_32_bits(req->pos)); 684 589 bp[5] = htonl(lower_32_bits(req->len)); 685 590 686 - atomic_inc(&req->usage); 591 + refcount_inc(&req->usage); 687 592 call->cb_break = fc->cb_break; 688 593 afs_use_fs_server(call, fc->cbi); 689 594 trace_afs_make_fs_call(call, &vnode->fid); ··· 708 613 /* unmarshall the reply once we've received all of it */ 709 614 bp = call->buffer; 710 615 xdr_decode_AFSFid(&bp, call->reply[1]); 711 - xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL); 712 - xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 616 + if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 || 617 + xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 618 + &call->expected_version, NULL) < 0) 619 + return afs_protocol_error(call, -EBADMSG); 713 620 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]); 714 621 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 715 622 ··· 742 645 int afs_fs_create(struct afs_fs_cursor *fc, 743 646 const char *name, 744 647 umode_t mode, 648 + u64 current_data_version, 745 649 struct afs_fid *newfid, 746 650 struct afs_file_status *newstatus, 747 651 struct afs_callback *newcb) ··· 770 672 call->reply[1] = newfid; 771 673 call->reply[2] = newstatus; 772 674 call->reply[3] = newcb; 675 + call->expected_version = current_data_version + 1; 773 676 774 677 /* marshall the parameters */ 775 678 bp = call->request; ··· 814 715 815 716 /* unmarshall the reply once we've received all of it */ 816 717 bp = call->buffer; 817 - xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 718 + if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 719 + &call->expected_version, NULL) < 0) 720 + return afs_protocol_error(call, -EBADMSG); 818 721 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 819 722 820 723 _leave(" = 0 [done]"); ··· 843 742 /* 844 743 * remove a file or directory 845 744 */ 846 - int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir) 745 + int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir, 746 + u64 current_data_version) 847 747 { 848 748 struct afs_vnode *vnode = fc->vnode; 849 749 struct afs_call *call; ··· 866 764 867 765 call->key = fc->key; 868 766 call->reply[0] = vnode; 767 + call->expected_version = current_data_version + 1; 869 768 870 769 /* marshall the parameters */ 871 770 bp = call->request; ··· 904 801 905 802 /* unmarshall the reply once we've received all of it */ 906 803 bp = call->buffer; 907 - xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 908 - xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL); 804 + if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 || 805 + xdr_decode_AFSFetchStatus(call, &bp, &dvnode->status, dvnode, 806 + &call->expected_version, NULL) < 0) 807 + return afs_protocol_error(call, -EBADMSG); 909 808 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 910 809 911 810 _leave(" = 0 [done]"); ··· 928 823 * make a hard link 929 824 */ 930 825 int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode, 931 - const char *name) 826 + const char *name, u64 current_data_version) 932 827 { 933 828 struct afs_vnode *dvnode = fc->vnode; 934 829 struct afs_call *call; ··· 949 844 call->key = fc->key; 950 845 call->reply[0] = dvnode; 951 846 call->reply[1] = vnode; 847 + call->expected_version = current_data_version + 1; 952 848 953 849 /* marshall the parameters */ 954 850 bp = call->request; ··· 991 885 /* unmarshall the reply once we've received all of it */ 992 886 bp = call->buffer; 993 887 xdr_decode_AFSFid(&bp, call->reply[1]); 994 - xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL); 995 - xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL); 888 + if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) || 889 + xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 890 + &call->expected_version, NULL) < 0) 891 + return afs_protocol_error(call, -EBADMSG); 996 892 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 997 893 998 894 _leave(" = 0 [done]"); ··· 1017 909 int afs_fs_symlink(struct afs_fs_cursor *fc, 1018 910 const char *name, 1019 911 const char *contents, 912 + u64 current_data_version, 1020 913 struct afs_fid *newfid, 1021 914 struct afs_file_status *newstatus) 1022 915 { ··· 1046 937 call->reply[0] = vnode; 1047 938 call->reply[1] = newfid; 1048 939 call->reply[2] = newstatus; 940 + call->expected_version = current_data_version + 1; 1049 941 1050 942 /* marshall the parameters */ 1051 943 bp = call->request; ··· 1097 987 1098 988 /* unmarshall the reply once we've received all of it */ 1099 989 bp = call->buffer; 1100 - xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL); 1101 - if (new_dvnode != orig_dvnode) 1102 - xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode, 1103 - NULL); 990 + if (xdr_decode_AFSFetchStatus(call, &bp, &orig_dvnode->status, orig_dvnode, 991 + &call->expected_version, NULL) < 0) 992 + return afs_protocol_error(call, -EBADMSG); 993 + if (new_dvnode != orig_dvnode && 994 + xdr_decode_AFSFetchStatus(call, &bp, &new_dvnode->status, new_dvnode, 995 + &call->expected_version_2, NULL) < 0) 996 + return afs_protocol_error(call, -EBADMSG); 1104 997 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1105 998 1106 999 _leave(" = 0 [done]"); ··· 1126 1013 int afs_fs_rename(struct afs_fs_cursor *fc, 1127 1014 const char *orig_name, 1128 1015 struct afs_vnode *new_dvnode, 1129 - const char *new_name) 1016 + const char *new_name, 1017 + u64 current_orig_data_version, 1018 + u64 current_new_data_version) 1130 1019 { 1131 1020 struct afs_vnode *orig_dvnode = fc->vnode; 1132 1021 struct afs_call *call; ··· 1156 1041 call->key = fc->key; 1157 1042 call->reply[0] = orig_dvnode; 1158 1043 call->reply[1] = new_dvnode; 1044 + call->expected_version = current_orig_data_version + 1; 1045 + call->expected_version_2 = current_new_data_version + 1; 1159 1046 1160 1047 /* marshall the parameters */ 1161 1048 bp = call->request; ··· 1206 1089 1207 1090 /* unmarshall the reply once we've received all of it */ 1208 1091 bp = call->buffer; 1209 - xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, 1210 - &call->store_version); 1092 + if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 1093 + &call->expected_version, NULL) < 0) 1094 + return afs_protocol_error(call, -EBADMSG); 1211 1095 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1212 1096 1213 1097 afs_pages_written_back(vnode, call); ··· 1265 1147 call->first_offset = offset; 1266 1148 call->last_to = to; 1267 1149 call->send_pages = true; 1268 - call->store_version = vnode->status.data_version + 1; 1150 + call->expected_version = vnode->status.data_version + 1; 1269 1151 1270 1152 /* marshall the parameters */ 1271 1153 bp = call->request; ··· 1340 1222 call->first_offset = offset; 1341 1223 call->last_to = to; 1342 1224 call->send_pages = true; 1343 - call->store_version = vnode->status.data_version + 1; 1225 + call->expected_version = vnode->status.data_version + 1; 1344 1226 1345 1227 /* marshall the parameters */ 1346 1228 bp = call->request; ··· 1370 1252 */ 1371 1253 static int afs_deliver_fs_store_status(struct afs_call *call) 1372 1254 { 1373 - afs_dataversion_t *store_version; 1374 1255 struct afs_vnode *vnode = call->reply[0]; 1375 1256 const __be32 *bp; 1376 1257 int ret; ··· 1381 1264 return ret; 1382 1265 1383 1266 /* unmarshall the reply once we've received all of it */ 1384 - store_version = NULL; 1385 - if (call->operation_ID == FSSTOREDATA) 1386 - store_version = &call->store_version; 1387 - 1388 1267 bp = call->buffer; 1389 - xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version); 1268 + if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 1269 + &call->expected_version, NULL) < 0) 1270 + return afs_protocol_error(call, -EBADMSG); 1390 1271 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1391 1272 1392 1273 _leave(" = 0 [done]"); ··· 1439 1324 1440 1325 call->key = fc->key; 1441 1326 call->reply[0] = vnode; 1442 - call->store_version = vnode->status.data_version + 1; 1327 + call->expected_version = vnode->status.data_version + 1; 1443 1328 1444 1329 /* marshall the parameters */ 1445 1330 bp = call->request; ··· 1488 1373 1489 1374 call->key = fc->key; 1490 1375 call->reply[0] = vnode; 1491 - call->store_version = vnode->status.data_version + 1; 1376 + call->expected_version = vnode->status.data_version + 1; 1492 1377 1493 1378 /* marshall the parameters */ 1494 1379 bp = call->request; ··· 1533 1418 1534 1419 call->key = fc->key; 1535 1420 call->reply[0] = vnode; 1421 + call->expected_version = vnode->status.data_version; 1536 1422 1537 1423 /* marshall the parameters */ 1538 1424 bp = call->request; ··· 1587 1471 call->count = ntohl(call->tmp); 1588 1472 _debug("volname length: %u", call->count); 1589 1473 if (call->count >= AFSNAMEMAX) 1590 - return -EBADMSG; 1474 + return afs_protocol_error(call, -EBADMSG); 1591 1475 call->offset = 0; 1592 1476 call->unmarshall++; 1593 1477 ··· 1634 1518 call->count = ntohl(call->tmp); 1635 1519 _debug("offline msg length: %u", call->count); 1636 1520 if (call->count >= AFSNAMEMAX) 1637 - return -EBADMSG; 1521 + return afs_protocol_error(call, -EBADMSG); 1638 1522 call->offset = 0; 1639 1523 call->unmarshall++; 1640 1524 ··· 1681 1565 call->count = ntohl(call->tmp); 1682 1566 _debug("motd length: %u", call->count); 1683 1567 if (call->count >= AFSNAMEMAX) 1684 - return -EBADMSG; 1568 + return afs_protocol_error(call, -EBADMSG); 1685 1569 call->offset = 0; 1686 1570 call->unmarshall++; 1687 1571 ··· 2062 1946 /* Can't take a ref on server */ 2063 1947 trace_afs_make_fs_call(call, NULL); 2064 1948 return afs_make_call(ac, call, GFP_NOFS, false); 1949 + } 1950 + 1951 + /* 1952 + * Deliver reply data to an FS.FetchStatus with no vnode. 1953 + */ 1954 + static int afs_deliver_fs_fetch_status(struct afs_call *call) 1955 + { 1956 + struct afs_file_status *status = call->reply[1]; 1957 + struct afs_callback *callback = call->reply[2]; 1958 + struct afs_volsync *volsync = call->reply[3]; 1959 + struct afs_vnode *vnode = call->reply[0]; 1960 + const __be32 *bp; 1961 + int ret; 1962 + 1963 + ret = afs_transfer_reply(call); 1964 + if (ret < 0) 1965 + return ret; 1966 + 1967 + _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode); 1968 + 1969 + /* unmarshall the reply once we've received all of it */ 1970 + bp = call->buffer; 1971 + xdr_decode_AFSFetchStatus(call, &bp, status, vnode, 1972 + &call->expected_version, NULL); 1973 + callback[call->count].version = ntohl(bp[0]); 1974 + callback[call->count].expiry = ntohl(bp[1]); 1975 + callback[call->count].type = ntohl(bp[2]); 1976 + if (vnode) 1977 + xdr_decode_AFSCallBack(call, vnode, &bp); 1978 + else 1979 + bp += 3; 1980 + if (volsync) 1981 + xdr_decode_AFSVolSync(&bp, volsync); 1982 + 1983 + _leave(" = 0 [done]"); 1984 + return 0; 1985 + } 1986 + 1987 + /* 1988 + * FS.FetchStatus operation type 1989 + */ 1990 + static const struct afs_call_type afs_RXFSFetchStatus = { 1991 + .name = "FS.FetchStatus", 1992 + .op = afs_FS_FetchStatus, 1993 + .deliver = afs_deliver_fs_fetch_status, 1994 + .destructor = afs_flat_call_destructor, 1995 + }; 1996 + 1997 + /* 1998 + * Fetch the status information for a fid without needing a vnode handle. 1999 + */ 2000 + int afs_fs_fetch_status(struct afs_fs_cursor *fc, 2001 + struct afs_net *net, 2002 + struct afs_fid *fid, 2003 + struct afs_file_status *status, 2004 + struct afs_callback *callback, 2005 + struct afs_volsync *volsync) 2006 + { 2007 + struct afs_call *call; 2008 + __be32 *bp; 2009 + 2010 + _enter(",%x,{%x:%u},,", 2011 + key_serial(fc->key), fid->vid, fid->vnode); 2012 + 2013 + call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4); 2014 + if (!call) { 2015 + fc->ac.error = -ENOMEM; 2016 + return -ENOMEM; 2017 + } 2018 + 2019 + call->key = fc->key; 2020 + call->reply[0] = NULL; /* vnode for fid[0] */ 2021 + call->reply[1] = status; 2022 + call->reply[2] = callback; 2023 + call->reply[3] = volsync; 2024 + call->expected_version = 1; /* vnode->status.data_version */ 2025 + 2026 + /* marshall the parameters */ 2027 + bp = call->request; 2028 + bp[0] = htonl(FSFETCHSTATUS); 2029 + bp[1] = htonl(fid->vid); 2030 + bp[2] = htonl(fid->vnode); 2031 + bp[3] = htonl(fid->unique); 2032 + 2033 + call->cb_break = fc->cb_break; 2034 + afs_use_fs_server(call, fc->cbi); 2035 + trace_afs_make_fs_call(call, fid); 2036 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 2037 + } 2038 + 2039 + /* 2040 + * Deliver reply data to an FS.InlineBulkStatus call 2041 + */ 2042 + static int afs_deliver_fs_inline_bulk_status(struct afs_call *call) 2043 + { 2044 + struct afs_file_status *statuses; 2045 + struct afs_callback *callbacks; 2046 + struct afs_vnode *vnode = call->reply[0]; 2047 + const __be32 *bp; 2048 + u32 tmp; 2049 + int ret; 2050 + 2051 + _enter("{%u}", call->unmarshall); 2052 + 2053 + switch (call->unmarshall) { 2054 + case 0: 2055 + call->offset = 0; 2056 + call->unmarshall++; 2057 + 2058 + /* Extract the file status count and array in two steps */ 2059 + case 1: 2060 + _debug("extract status count"); 2061 + ret = afs_extract_data(call, &call->tmp, 4, true); 2062 + if (ret < 0) 2063 + return ret; 2064 + 2065 + tmp = ntohl(call->tmp); 2066 + _debug("status count: %u/%u", tmp, call->count2); 2067 + if (tmp != call->count2) 2068 + return afs_protocol_error(call, -EBADMSG); 2069 + 2070 + call->count = 0; 2071 + call->unmarshall++; 2072 + more_counts: 2073 + call->offset = 0; 2074 + 2075 + case 2: 2076 + _debug("extract status array %u", call->count); 2077 + ret = afs_extract_data(call, call->buffer, 21 * 4, true); 2078 + if (ret < 0) 2079 + return ret; 2080 + 2081 + bp = call->buffer; 2082 + statuses = call->reply[1]; 2083 + if (xdr_decode_AFSFetchStatus(call, &bp, &statuses[call->count], 2084 + call->count == 0 ? vnode : NULL, 2085 + NULL, NULL) < 0) 2086 + return afs_protocol_error(call, -EBADMSG); 2087 + 2088 + call->count++; 2089 + if (call->count < call->count2) 2090 + goto more_counts; 2091 + 2092 + call->count = 0; 2093 + call->unmarshall++; 2094 + call->offset = 0; 2095 + 2096 + /* Extract the callback count and array in two steps */ 2097 + case 3: 2098 + _debug("extract CB count"); 2099 + ret = afs_extract_data(call, &call->tmp, 4, true); 2100 + if (ret < 0) 2101 + return ret; 2102 + 2103 + tmp = ntohl(call->tmp); 2104 + _debug("CB count: %u", tmp); 2105 + if (tmp != call->count2) 2106 + return afs_protocol_error(call, -EBADMSG); 2107 + call->count = 0; 2108 + call->unmarshall++; 2109 + more_cbs: 2110 + call->offset = 0; 2111 + 2112 + case 4: 2113 + _debug("extract CB array"); 2114 + ret = afs_extract_data(call, call->buffer, 3 * 4, true); 2115 + if (ret < 0) 2116 + return ret; 2117 + 2118 + _debug("unmarshall CB array"); 2119 + bp = call->buffer; 2120 + callbacks = call->reply[2]; 2121 + callbacks[call->count].version = ntohl(bp[0]); 2122 + callbacks[call->count].expiry = ntohl(bp[1]); 2123 + callbacks[call->count].type = ntohl(bp[2]); 2124 + statuses = call->reply[1]; 2125 + if (call->count == 0 && vnode && statuses[0].abort_code == 0) 2126 + xdr_decode_AFSCallBack(call, vnode, &bp); 2127 + call->count++; 2128 + if (call->count < call->count2) 2129 + goto more_cbs; 2130 + 2131 + call->offset = 0; 2132 + call->unmarshall++; 2133 + 2134 + case 5: 2135 + ret = afs_extract_data(call, call->buffer, 6 * 4, false); 2136 + if (ret < 0) 2137 + return ret; 2138 + 2139 + bp = call->buffer; 2140 + if (call->reply[3]) 2141 + xdr_decode_AFSVolSync(&bp, call->reply[3]); 2142 + 2143 + call->offset = 0; 2144 + call->unmarshall++; 2145 + 2146 + case 6: 2147 + break; 2148 + } 2149 + 2150 + _leave(" = 0 [done]"); 2151 + return 0; 2152 + } 2153 + 2154 + /* 2155 + * FS.InlineBulkStatus operation type 2156 + */ 2157 + static const struct afs_call_type afs_RXFSInlineBulkStatus = { 2158 + .name = "FS.InlineBulkStatus", 2159 + .op = afs_FS_InlineBulkStatus, 2160 + .deliver = afs_deliver_fs_inline_bulk_status, 2161 + .destructor = afs_flat_call_destructor, 2162 + }; 2163 + 2164 + /* 2165 + * Fetch the status information for up to 50 files 2166 + */ 2167 + int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc, 2168 + struct afs_net *net, 2169 + struct afs_fid *fids, 2170 + struct afs_file_status *statuses, 2171 + struct afs_callback *callbacks, 2172 + unsigned int nr_fids, 2173 + struct afs_volsync *volsync) 2174 + { 2175 + struct afs_call *call; 2176 + __be32 *bp; 2177 + int i; 2178 + 2179 + _enter(",%x,{%x:%u},%u", 2180 + key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids); 2181 + 2182 + call = afs_alloc_flat_call(net, &afs_RXFSInlineBulkStatus, 2183 + (2 + nr_fids * 3) * 4, 2184 + 21 * 4); 2185 + if (!call) { 2186 + fc->ac.error = -ENOMEM; 2187 + return -ENOMEM; 2188 + } 2189 + 2190 + call->key = fc->key; 2191 + call->reply[0] = NULL; /* vnode for fid[0] */ 2192 + call->reply[1] = statuses; 2193 + call->reply[2] = callbacks; 2194 + call->reply[3] = volsync; 2195 + call->count2 = nr_fids; 2196 + 2197 + /* marshall the parameters */ 2198 + bp = call->request; 2199 + *bp++ = htonl(FSINLINEBULKSTATUS); 2200 + *bp++ = htonl(nr_fids); 2201 + for (i = 0; i < nr_fids; i++) { 2202 + *bp++ = htonl(fids[i].vid); 2203 + *bp++ = htonl(fids[i].vnode); 2204 + *bp++ = htonl(fids[i].unique); 2205 + } 2206 + 2207 + call->cb_break = fc->cb_break; 2208 + afs_use_fs_server(call, fc->cbi); 2209 + trace_afs_make_fs_call(call, &fids[0]); 2210 + return afs_make_call(&fc->ac, call, GFP_NOFS, false); 2065 2211 }
+29 -40
fs/afs/inode.c
··· 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 */ 35 - static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) 35 + static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key) 36 36 { 37 37 struct inode *inode = AFS_VNODE_TO_I(vnode); 38 - bool changed; 39 38 40 39 _debug("FS: ft=%d lk=%d sz=%llu ver=%Lu mod=%hu", 41 40 vnode->status.type, ··· 45 46 46 47 read_seqlock_excl(&vnode->cb_lock); 47 48 49 + afs_update_inode_from_status(vnode, &vnode->status, NULL, 50 + AFS_VNODE_NOT_YET_SET); 51 + 48 52 switch (vnode->status.type) { 49 53 case AFS_FTYPE_FILE: 50 54 inode->i_mode = S_IFREG | vnode->status.mode; 51 55 inode->i_op = &afs_file_inode_operations; 52 56 inode->i_fop = &afs_file_operations; 57 + inode->i_mapping->a_ops = &afs_fs_aops; 53 58 break; 54 59 case AFS_FTYPE_DIR: 55 60 inode->i_mode = S_IFDIR | vnode->status.mode; 56 61 inode->i_op = &afs_dir_inode_operations; 57 62 inode->i_fop = &afs_dir_file_operations; 63 + inode->i_mapping->a_ops = &afs_dir_aops; 58 64 break; 59 65 case AFS_FTYPE_SYMLINK: 60 66 /* Symlinks with a mode of 0644 are actually mountpoints. */ ··· 71 67 inode->i_mode = S_IFDIR | 0555; 72 68 inode->i_op = &afs_mntpt_inode_operations; 73 69 inode->i_fop = &afs_mntpt_file_operations; 70 + inode->i_mapping->a_ops = &afs_fs_aops; 74 71 } else { 75 72 inode->i_mode = S_IFLNK | vnode->status.mode; 76 73 inode->i_op = &afs_symlink_inode_operations; 74 + inode->i_mapping->a_ops = &afs_fs_aops; 77 75 } 78 76 inode_nohighmem(inode); 79 77 break; 80 78 default: 81 79 printk("kAFS: AFS vnode with undefined type\n"); 82 80 read_sequnlock_excl(&vnode->cb_lock); 83 - return -EBADMSG; 81 + return afs_protocol_error(NULL, -EBADMSG); 84 82 } 85 83 86 - changed = (vnode->status.size != inode->i_size); 87 - 88 - set_nlink(inode, vnode->status.nlink); 89 - inode->i_uid = vnode->status.owner; 90 - inode->i_gid = vnode->status.group; 91 - inode->i_size = vnode->status.size; 92 - inode->i_ctime.tv_sec = vnode->status.mtime_client; 93 - inode->i_ctime.tv_nsec = 0; 94 - inode->i_atime = inode->i_mtime = inode->i_ctime; 95 84 inode->i_blocks = 0; 96 - inode->i_generation = vnode->fid.unique; 97 - inode_set_iversion_raw(inode, vnode->status.data_version); 98 - inode->i_mapping->a_ops = &afs_fs_aops; 85 + vnode->invalid_before = vnode->status.data_version; 99 86 100 87 read_sequnlock_excl(&vnode->cb_lock); 101 - 102 - #ifdef CONFIG_AFS_FSCACHE 103 - if (changed) 104 - fscache_attr_changed(vnode->cache); 105 - #endif 106 88 return 0; 107 89 } 108 90 109 91 /* 110 92 * Fetch file status from the volume. 111 93 */ 112 - int afs_fetch_status(struct afs_vnode *vnode, struct key *key) 94 + int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool new_inode) 113 95 { 114 96 struct afs_fs_cursor fc; 115 97 int ret; ··· 109 119 if (afs_begin_vnode_operation(&fc, vnode, key)) { 110 120 while (afs_select_fileserver(&fc)) { 111 121 fc.cb_break = vnode->cb_break + vnode->cb_s_break; 112 - afs_fs_fetch_file_status(&fc, NULL); 122 + afs_fs_fetch_file_status(&fc, NULL, new_inode); 113 123 } 114 124 115 125 afs_check_for_remote_deletion(&fc, fc.vnode); ··· 245 255 } __packed key; 246 256 struct afs_vnode_cache_aux aux; 247 257 258 + if (vnode->status.type == AFS_FTYPE_DIR) { 259 + vnode->cache = NULL; 260 + return; 261 + } 262 + 248 263 key.vnode_id = vnode->fid.vnode; 249 264 key.unique = vnode->fid.unique; 250 265 key.vnode_id_ext[0] = 0; ··· 302 307 303 308 if (!status) { 304 309 /* it's a remotely extant inode */ 305 - ret = afs_fetch_status(vnode, key); 310 + ret = afs_fetch_status(vnode, key, true); 306 311 if (ret < 0) 307 312 goto bad_inode; 308 313 } else { ··· 326 331 vnode->cb_expires_at += ktime_get_real_seconds(); 327 332 } 328 333 329 - /* set up caching before mapping the status, as map-status reads the 330 - * first page of symlinks to see if they're really mountpoints */ 331 - inode->i_size = vnode->status.size; 332 - afs_get_inode_cache(vnode); 333 - 334 - ret = afs_inode_map_status(vnode, key); 334 + ret = afs_inode_init_from_status(vnode, key); 335 335 if (ret < 0) 336 336 goto bad_inode; 337 + 338 + afs_get_inode_cache(vnode); 337 339 338 340 /* success */ 339 341 clear_bit(AFS_VNODE_UNSET, &vnode->flags); ··· 341 349 342 350 /* failure */ 343 351 bad_inode: 344 - #ifdef CONFIG_AFS_FSCACHE 345 - fscache_relinquish_cookie(vnode->cache, NULL, ret == -ENOENT); 346 - vnode->cache = NULL; 347 - #endif 348 352 iget_failed(inode); 349 353 _leave(" = %d [bad]", ret); 350 354 return ERR_PTR(ret); ··· 395 407 if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { 396 408 if (vnode->cb_s_break != vnode->cb_interest->server->cb_s_break) { 397 409 vnode->cb_s_break = vnode->cb_interest->server->cb_s_break; 398 - } else if (!test_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags) && 399 - !test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) && 410 + } else if (vnode->status.type == AFS_FTYPE_DIR && 411 + test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) && 412 + vnode->cb_expires_at - 10 > now) { 413 + valid = true; 414 + } else if (!test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) && 400 415 vnode->cb_expires_at - 10 > now) { 401 416 valid = true; 402 417 } ··· 423 432 * access */ 424 433 if (!test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { 425 434 _debug("not promised"); 426 - ret = afs_fetch_status(vnode, key); 435 + ret = afs_fetch_status(vnode, key, false); 427 436 if (ret < 0) { 428 437 if (ret == -ENOENT) { 429 438 set_bit(AFS_VNODE_DELETED, &vnode->flags); ··· 444 453 * different */ 445 454 if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) 446 455 afs_zap_data(vnode); 447 - 448 - clear_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags); 449 456 mutex_unlock(&vnode->validate_lock); 450 457 valid: 451 458 _leave(" = 0"); ··· 533 544 } 534 545 #endif 535 546 536 - afs_put_permits(vnode->permit_cache); 547 + afs_put_permits(rcu_access_pointer(vnode->permit_cache)); 537 548 _leave(""); 538 549 } 539 550
+89 -18
fs/afs/internal.h
··· 122 122 u32 operation_ID; /* operation ID for an incoming call */ 123 123 u32 count; /* count for use in unmarshalling */ 124 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 128 129 struct afs_call_type { ··· 174 173 loff_t len; /* How much we're asking for */ 175 174 loff_t actual_len; /* How much we're actually getting */ 176 175 loff_t remain; /* Amount remaining */ 177 - atomic_t usage; 176 + loff_t file_size; /* File size returned by server */ 177 + afs_dataversion_t data_version; /* Version number returned by server */ 178 + refcount_t usage; 178 179 unsigned int index; /* Which page we're reading into */ 179 180 unsigned int nr_pages; 180 181 void (*page_done)(struct afs_call *, struct afs_read *); 181 - struct page *pages[]; 182 + struct page **pages; 183 + struct page *array[]; 182 184 }; 183 185 184 186 /* ··· 201 197 } 202 198 203 199 extern struct file_system_type afs_fs_type; 200 + 201 + /* 202 + * Set of substitutes for @sys. 203 + */ 204 + struct afs_sysnames { 205 + #define AFS_NR_SYSNAME 16 206 + char *subs[AFS_NR_SYSNAME]; 207 + refcount_t usage; 208 + unsigned short nr; 209 + short error; 210 + char blank[1]; 211 + }; 204 212 205 213 /* 206 214 * AFS network namespace record. ··· 261 245 struct mutex lock_manager_mutex; 262 246 263 247 /* Misc */ 264 - struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */ 248 + struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */ 249 + struct afs_sysnames *sysnames; 250 + rwlock_t sysnames_lock; 251 + 252 + /* Statistics counters */ 253 + atomic_t n_lookup; /* Number of lookups done */ 254 + atomic_t n_reval; /* Number of dentries needing revalidation */ 255 + atomic_t n_inval; /* Number of invalidations by the server */ 256 + atomic_t n_relpg; /* Number of invalidations by releasepage */ 257 + atomic_t n_read_dir; /* Number of directory pages read */ 258 + atomic_t n_dir_cr; /* Number of directory entry creation edits */ 259 + atomic_t n_dir_rm; /* Number of directory entry removal edits */ 260 + atomic_t n_stores; /* Number of store ops */ 261 + atomic_long_t n_store_bytes; /* Number of bytes stored */ 262 + atomic_long_t n_fetch_bytes; /* Number of bytes fetched */ 263 + atomic_t n_fetches; /* Number of data fetch ops */ 265 264 }; 266 265 266 + extern const char afs_init_sysname[]; 267 267 extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns 268 268 269 269 enum afs_cell_state { ··· 395 363 #define AFS_SERVER_FL_UPDATING 4 396 364 #define AFS_SERVER_FL_PROBED 5 /* The fileserver has been probed */ 397 365 #define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */ 366 + #define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */ 398 367 atomic_t usage; 399 368 u32 addr_version; /* Address list version */ 400 369 ··· 488 455 struct afs_volume *volume; /* volume on which vnode resides */ 489 456 struct afs_fid fid; /* the file identifier for this inode */ 490 457 struct afs_file_status status; /* AFS status info for this file */ 458 + afs_dataversion_t invalid_before; /* Child dentries are invalid before this */ 491 459 #ifdef CONFIG_AFS_FSCACHE 492 460 struct fscache_cookie *cache; /* caching cookie */ 493 461 #endif 494 - struct afs_permits *permit_cache; /* cache of permits so far obtained */ 462 + struct afs_permits __rcu *permit_cache; /* cache of permits so far obtained */ 495 463 struct mutex io_lock; /* Lock for serialising I/O on this mutex */ 496 464 struct mutex validate_lock; /* lock for validating this vnode */ 497 465 spinlock_t wb_lock; /* lock for wb_keys */ ··· 500 466 unsigned long flags; 501 467 #define AFS_VNODE_CB_PROMISED 0 /* Set if vnode has a callback promise */ 502 468 #define AFS_VNODE_UNSET 1 /* set if vnode attributes not yet set */ 503 - #define AFS_VNODE_DIR_MODIFIED 2 /* set if dir vnode's data modified */ 469 + #define AFS_VNODE_DIR_VALID 2 /* Set if dir contents are valid */ 504 470 #define AFS_VNODE_ZAP_DATA 3 /* set if vnode's data should be invalidated */ 505 471 #define AFS_VNODE_DELETED 4 /* set if vnode deleted on server */ 506 472 #define AFS_VNODE_MOUNTPOINT 5 /* set if vnode is a mountpoint symlink */ 507 473 #define AFS_VNODE_AUTOCELL 6 /* set if Vnode is an auto mount point */ 508 474 #define AFS_VNODE_PSEUDODIR 7 /* set if Vnode is a pseudo directory */ 475 + #define AFS_VNODE_NEW_CONTENT 8 /* Set if file has new content (create/trunc-0) */ 509 476 510 477 struct list_head wb_keys; /* List of keys available for writeback */ 511 478 struct list_head pending_locks; /* locks waiting to be granted */ ··· 646 611 */ 647 612 extern void afs_init_callback_state(struct afs_server *); 648 613 extern void afs_break_callback(struct afs_vnode *); 649 - extern void afs_break_callbacks(struct afs_server *, size_t,struct afs_callback[]); 614 + extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*); 650 615 651 616 extern int afs_register_server_cb_interest(struct afs_vnode *, struct afs_server_entry *); 652 617 extern void afs_put_cb_interest(struct afs_net *, struct afs_cb_interest *); ··· 681 646 */ 682 647 extern const struct file_operations afs_dir_file_operations; 683 648 extern const struct inode_operations afs_dir_inode_operations; 684 - extern const struct file_operations afs_dynroot_file_operations; 685 - extern const struct inode_operations afs_dynroot_inode_operations; 649 + extern const struct address_space_operations afs_dir_aops; 686 650 extern const struct dentry_operations afs_fs_dentry_operations; 687 651 688 - extern bool afs_dir_check_page(struct inode *, struct page *); 652 + extern void afs_d_release(struct dentry *); 653 + 654 + /* 655 + * dir_edit.c 656 + */ 657 + extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *, 658 + enum afs_edit_dir_reason); 659 + extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason); 660 + 661 + /* 662 + * dynroot.c 663 + */ 664 + extern const struct file_operations afs_dynroot_file_operations; 665 + extern const struct inode_operations afs_dynroot_inode_operations; 666 + extern const struct dentry_operations afs_dynroot_dentry_operations; 667 + 668 + extern struct inode *afs_try_auto_mntpt(struct dentry *, struct inode *); 689 669 690 670 /* 691 671 * file.c ··· 730 680 /* 731 681 * fsclient.c 732 682 */ 733 - extern int afs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_volsync *); 683 + #define AFS_VNODE_NOT_YET_SET 0x01 684 + #define AFS_VNODE_META_CHANGED 0x02 685 + #define AFS_VNODE_DATA_CHANGED 0x04 686 + extern void afs_update_inode_from_status(struct afs_vnode *, struct afs_file_status *, 687 + const afs_dataversion_t *, u8); 688 + 689 + extern int afs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_volsync *, bool); 734 690 extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *); 735 691 extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct afs_read *); 736 - extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t, 692 + extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t, u64, 737 693 struct afs_fid *, struct afs_file_status *, struct afs_callback *); 738 - extern int afs_fs_remove(struct afs_fs_cursor *, const char *, bool); 739 - extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *); 740 - extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, 694 + extern int afs_fs_remove(struct afs_fs_cursor *, const char *, bool, u64); 695 + extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64); 696 + extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, u64, 741 697 struct afs_fid *, struct afs_file_status *); 742 698 extern int afs_fs_rename(struct afs_fs_cursor *, const char *, 743 - struct afs_vnode *, const char *); 699 + struct afs_vnode *, const char *, u64, u64); 744 700 extern int afs_fs_store_data(struct afs_fs_cursor *, struct address_space *, 745 701 pgoff_t, pgoff_t, unsigned, unsigned); 746 702 extern int afs_fs_setattr(struct afs_fs_cursor *, struct iattr *); ··· 758 702 struct afs_addr_cursor *, struct key *); 759 703 extern int afs_fs_get_capabilities(struct afs_net *, struct afs_server *, 760 704 struct afs_addr_cursor *, struct key *); 705 + extern int afs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *, 706 + struct afs_fid *, struct afs_file_status *, 707 + struct afs_callback *, unsigned int, 708 + struct afs_volsync *); 709 + extern int afs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *, 710 + struct afs_fid *, struct afs_file_status *, 711 + struct afs_callback *, struct afs_volsync *); 761 712 762 713 /* 763 714 * inode.c 764 715 */ 765 - extern int afs_fetch_status(struct afs_vnode *, struct key *); 716 + extern int afs_fetch_status(struct afs_vnode *, struct key *, bool); 766 717 extern int afs_iget5_test(struct inode *, void *); 767 718 extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool); 768 719 extern struct inode *afs_iget(struct super_block *, struct key *, ··· 817 754 { 818 755 } 819 756 757 + static inline void __afs_stat(atomic_t *s) 758 + { 759 + atomic_inc(s); 760 + } 761 + 762 + #define afs_stat_v(vnode, n) __afs_stat(&afs_v2net(vnode)->n) 763 + 820 764 /* 821 765 * misc.c 822 766 */ ··· 851 781 extern void __net_exit afs_proc_cleanup(struct afs_net *); 852 782 extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *); 853 783 extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *); 784 + extern void afs_put_sysnames(struct afs_sysnames *); 854 785 855 786 /* 856 787 * rotate.c ··· 880 809 extern void afs_send_empty_reply(struct afs_call *); 881 810 extern void afs_send_simple_reply(struct afs_call *, const void *, size_t); 882 811 extern int afs_extract_data(struct afs_call *, void *, size_t, bool); 812 + extern int afs_protocol_error(struct afs_call *, int); 883 813 884 814 static inline int afs_transfer_reply(struct afs_call *call) 885 815 { ··· 1027 955 extern int afs_writepages(struct address_space *, struct writeback_control *); 1028 956 extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); 1029 957 extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *); 1030 - extern int afs_flush(struct file *, fl_owner_t); 1031 958 extern int afs_fsync(struct file *, loff_t, loff_t, int); 1032 959 extern int afs_page_mkwrite(struct vm_fault *); 1033 960 extern void afs_prune_wb_keys(struct afs_vnode *);
+44
fs/afs/main.c
··· 34 34 struct workqueue_struct *afs_wq; 35 35 struct afs_net __afs_net; 36 36 37 + #if defined(CONFIG_ALPHA) 38 + const char afs_init_sysname[] = "alpha_linux26"; 39 + #elif defined(CONFIG_X86_64) 40 + const char afs_init_sysname[] = "amd64_linux26"; 41 + #elif defined(CONFIG_ARM) 42 + const char afs_init_sysname[] = "arm_linux26"; 43 + #elif defined(CONFIG_ARM64) 44 + const char afs_init_sysname[] = "aarch64_linux26"; 45 + #elif defined(CONFIG_X86_32) 46 + const char afs_init_sysname[] = "i386_linux26"; 47 + #elif defined(CONFIG_IA64) 48 + const char afs_init_sysname[] = "ia64_linux26"; 49 + #elif defined(CONFIG_PPC64) 50 + const char afs_init_sysname[] = "ppc64_linux26"; 51 + #elif defined(CONFIG_PPC32) 52 + const char afs_init_sysname[] = "ppc_linux26"; 53 + #elif defined(CONFIG_S390) 54 + #ifdef CONFIG_64BIT 55 + const char afs_init_sysname[] = "s390x_linux26"; 56 + #else 57 + const char afs_init_sysname[] = "s390_linux26"; 58 + #endif 59 + #elif defined(CONFIG_SPARC64) 60 + const char afs_init_sysname[] = "sparc64_linux26"; 61 + #elif defined(CONFIG_SPARC32) 62 + const char afs_init_sysname[] = "sparc_linux26"; 63 + #else 64 + const char afs_init_sysname[] = "unknown_linux26"; 65 + #endif 66 + 37 67 /* 38 68 * Initialise an AFS network namespace record. 39 69 */ 40 70 static int __net_init afs_net_init(struct afs_net *net) 41 71 { 72 + struct afs_sysnames *sysnames; 42 73 int ret; 43 74 44 75 net->live = true; ··· 98 67 INIT_WORK(&net->fs_manager, afs_manage_servers); 99 68 timer_setup(&net->fs_timer, afs_servers_timer, 0); 100 69 70 + ret = -ENOMEM; 71 + sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); 72 + if (!sysnames) 73 + goto error_sysnames; 74 + sysnames->subs[0] = (char *)&afs_init_sysname; 75 + sysnames->nr = 1; 76 + refcount_set(&sysnames->usage, 1); 77 + net->sysnames = sysnames; 78 + rwlock_init(&net->sysnames_lock); 79 + 101 80 /* Register the /proc stuff */ 102 81 ret = afs_proc_init(net); 103 82 if (ret < 0) ··· 133 92 net->live = false; 134 93 afs_proc_cleanup(net); 135 94 error_proc: 95 + afs_put_sysnames(net->sysnames); 96 + error_sysnames: 136 97 net->live = false; 137 98 return ret; 138 99 } ··· 149 106 afs_purge_servers(net); 150 107 afs_close_socket(net); 151 108 afs_proc_cleanup(net); 109 + afs_put_sysnames(net->sysnames); 152 110 } 153 111 154 112 /*
+323 -3
fs/afs/proc.c
··· 126 126 .release = seq_release, 127 127 }; 128 128 129 + static int afs_proc_sysname_open(struct inode *inode, struct file *file); 130 + static int afs_proc_sysname_release(struct inode *inode, struct file *file); 131 + static void *afs_proc_sysname_start(struct seq_file *p, loff_t *pos); 132 + static void *afs_proc_sysname_next(struct seq_file *p, void *v, 133 + loff_t *pos); 134 + static void afs_proc_sysname_stop(struct seq_file *p, void *v); 135 + static int afs_proc_sysname_show(struct seq_file *m, void *v); 136 + static ssize_t afs_proc_sysname_write(struct file *file, 137 + const char __user *buf, 138 + size_t size, loff_t *_pos); 139 + 140 + static 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 + 147 + static 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 + 155 + static const struct file_operations afs_proc_stats_fops; 156 + 129 157 /* 130 158 * initialise the /proc/fs/afs/ directory 131 159 */ ··· 167 139 168 140 if (!proc_create("cells", 0644, net->proc_afs, &afs_proc_cells_fops) || 169 141 !proc_create("rootcell", 0644, net->proc_afs, &afs_proc_rootcell_fops) || 170 - !proc_create("servers", 0644, net->proc_afs, &afs_proc_servers_fops)) 142 + !proc_create("servers", 0644, net->proc_afs, &afs_proc_servers_fops) || 143 + !proc_create("stats", 0644, net->proc_afs, &afs_proc_stats_fops) || 144 + !proc_create("sysname", 0644, net->proc_afs, &afs_proc_sysname_fops)) 171 145 goto error_tree; 172 146 173 147 _leave(" = 0"); ··· 213 183 * first item 214 184 */ 215 185 static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos) 186 + __acquires(rcu) 216 187 { 217 188 struct afs_net *net = afs_seq2net(m); 218 189 ··· 235 204 * clean up after reading from the cells list 236 205 */ 237 206 static void afs_proc_cells_stop(struct seq_file *m, void *v) 207 + __releases(rcu) 238 208 { 239 209 rcu_read_unlock(); 240 210 } ··· 314 282 goto done; 315 283 } 316 284 317 - set_bit(AFS_CELL_FL_NO_GC, &cell->flags); 285 + if (test_and_set_bit(AFS_CELL_FL_NO_GC, &cell->flags)) 286 + afs_put_cell(net, cell); 318 287 printk("kAFS: Added new cell '%s'\n", name); 319 288 } else { 320 289 goto inval; ··· 337 304 static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, 338 305 size_t size, loff_t *_pos) 339 306 { 340 - return 0; 307 + struct afs_cell *cell; 308 + struct afs_net *net = afs_proc2net(file); 309 + unsigned int seq = 0; 310 + char name[AFS_MAXCELLNAME + 1]; 311 + int len; 312 + 313 + if (*_pos > 0) 314 + return 0; 315 + if (!net->ws_cell) 316 + return 0; 317 + 318 + rcu_read_lock(); 319 + do { 320 + read_seqbegin_or_lock(&net->cells_lock, &seq); 321 + len = 0; 322 + cell = rcu_dereference_raw(net->ws_cell); 323 + if (cell) { 324 + len = cell->name_len; 325 + memcpy(name, cell->name, len); 326 + } 327 + } while (need_seqretry(&net->cells_lock, seq)); 328 + done_seqretry(&net->cells_lock, seq); 329 + rcu_read_unlock(); 330 + 331 + if (!len) 332 + return 0; 333 + 334 + name[len++] = '\n'; 335 + if (len > size) 336 + len = size; 337 + if (copy_to_user(buf, name, len) != 0) 338 + return -EFAULT; 339 + *_pos = 1; 340 + return len; 341 341 } 342 342 343 343 /* ··· 393 327 if (IS_ERR(kbuf)) 394 328 return PTR_ERR(kbuf); 395 329 330 + ret = -EINVAL; 331 + if (kbuf[0] == '.') 332 + goto out; 333 + if (memchr(kbuf, '/', size)) 334 + goto out; 335 + 396 336 /* trim to first NL */ 397 337 s = memchr(kbuf, '\n', size); 398 338 if (s) ··· 411 339 if (ret >= 0) 412 340 ret = size; /* consume everything, always */ 413 341 342 + out: 414 343 kfree(kbuf); 415 344 _leave(" = %d", ret); 416 345 return ret; ··· 486 413 * first item 487 414 */ 488 415 static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos) 416 + __acquires(cell->proc_lock) 489 417 { 490 418 struct afs_cell *cell = m->private; 491 419 ··· 512 438 * clean up after reading from the cells list 513 439 */ 514 440 static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v) 441 + __releases(cell->proc_lock) 515 442 { 516 443 struct afs_cell *cell = p->private; 517 444 ··· 575 500 * first item 576 501 */ 577 502 static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) 503 + __acquires(rcu) 578 504 { 579 505 struct afs_addr_list *alist; 580 506 struct afs_cell *cell = m->private; ··· 620 544 * clean up after reading from the cells list 621 545 */ 622 546 static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v) 547 + __releases(rcu) 623 548 { 624 549 rcu_read_unlock(); 625 550 } ··· 657 580 * first item. 658 581 */ 659 582 static void *afs_proc_servers_start(struct seq_file *m, loff_t *_pos) 583 + __acquires(rcu) 660 584 { 661 585 struct afs_net *net = afs_seq2net(m); 662 586 ··· 679 601 * clean up after reading from the cells list 680 602 */ 681 603 static void afs_proc_servers_stop(struct seq_file *p, void *v) 604 + __releases(rcu) 682 605 { 683 606 rcu_read_unlock(); 684 607 } ··· 705 626 &alist->addrs[alist->index].transport); 706 627 return 0; 707 628 } 629 + 630 + void afs_put_sysnames(struct afs_sysnames *sysnames) 631 + { 632 + int i; 633 + 634 + if (sysnames && refcount_dec_and_test(&sysnames->usage)) { 635 + for (i = 0; i < sysnames->nr; i++) 636 + if (sysnames->subs[i] != afs_init_sysname && 637 + sysnames->subs[i] != sysnames->blank) 638 + kfree(sysnames->subs[i]); 639 + } 640 + } 641 + 642 + /* 643 + * Handle opening of /proc/fs/afs/sysname. If it is opened for writing, we 644 + * assume the caller wants to change the substitution list and we allocate a 645 + * buffer to hold the list. 646 + */ 647 + static int afs_proc_sysname_open(struct inode *inode, struct file *file) 648 + { 649 + struct afs_sysnames *sysnames; 650 + struct seq_file *m; 651 + int ret; 652 + 653 + ret = seq_open(file, &afs_proc_sysname_ops); 654 + if (ret < 0) 655 + return ret; 656 + 657 + if (file->f_mode & FMODE_WRITE) { 658 + sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); 659 + if (!sysnames) { 660 + seq_release(inode, file); 661 + return -ENOMEM; 662 + } 663 + 664 + refcount_set(&sysnames->usage, 1); 665 + m = file->private_data; 666 + m->private = sysnames; 667 + } 668 + 669 + return 0; 670 + } 671 + 672 + /* 673 + * Handle writes to /proc/fs/afs/sysname to set the @sys substitution. 674 + */ 675 + static ssize_t afs_proc_sysname_write(struct file *file, 676 + const char __user *buf, 677 + size_t size, loff_t *_pos) 678 + { 679 + struct afs_sysnames *sysnames; 680 + struct seq_file *m = file->private_data; 681 + char *kbuf = NULL, *s, *p, *sub; 682 + int ret, len; 683 + 684 + sysnames = m->private; 685 + if (!sysnames) 686 + return -EINVAL; 687 + if (sysnames->error) 688 + return sysnames->error; 689 + 690 + if (size >= PAGE_SIZE - 1) { 691 + sysnames->error = -EINVAL; 692 + return -EINVAL; 693 + } 694 + if (size == 0) 695 + return 0; 696 + 697 + kbuf = memdup_user_nul(buf, size); 698 + if (IS_ERR(kbuf)) 699 + return PTR_ERR(kbuf); 700 + 701 + inode_lock(file_inode(file)); 702 + 703 + p = kbuf; 704 + while ((s = strsep(&p, " \t\n"))) { 705 + len = strlen(s); 706 + if (len == 0) 707 + continue; 708 + ret = -ENAMETOOLONG; 709 + if (len >= AFSNAMEMAX) 710 + goto error; 711 + 712 + if (len >= 4 && 713 + s[len - 4] == '@' && 714 + s[len - 3] == 's' && 715 + s[len - 2] == 'y' && 716 + s[len - 1] == 's') 717 + /* Protect against recursion */ 718 + goto invalid; 719 + 720 + if (s[0] == '.' && 721 + (len < 2 || (len == 2 && s[1] == '.'))) 722 + goto invalid; 723 + 724 + if (memchr(s, '/', len)) 725 + goto invalid; 726 + 727 + ret = -EFBIG; 728 + if (sysnames->nr >= AFS_NR_SYSNAME) 729 + goto out; 730 + 731 + if (strcmp(s, afs_init_sysname) == 0) { 732 + sub = (char *)afs_init_sysname; 733 + } else { 734 + ret = -ENOMEM; 735 + sub = kmemdup(s, len + 1, GFP_KERNEL); 736 + if (!sub) 737 + goto out; 738 + } 739 + 740 + sysnames->subs[sysnames->nr] = sub; 741 + sysnames->nr++; 742 + } 743 + 744 + ret = size; /* consume everything, always */ 745 + out: 746 + inode_unlock(file_inode(file)); 747 + kfree(kbuf); 748 + return ret; 749 + 750 + invalid: 751 + ret = -EINVAL; 752 + error: 753 + sysnames->error = ret; 754 + goto out; 755 + } 756 + 757 + static int afs_proc_sysname_release(struct inode *inode, struct file *file) 758 + { 759 + struct afs_sysnames *sysnames, *kill = NULL; 760 + struct seq_file *m = file->private_data; 761 + struct afs_net *net = afs_seq2net(m); 762 + 763 + sysnames = m->private; 764 + if (sysnames) { 765 + if (!sysnames->error) { 766 + kill = sysnames; 767 + if (sysnames->nr == 0) { 768 + sysnames->subs[0] = sysnames->blank; 769 + sysnames->nr++; 770 + } 771 + write_lock(&net->sysnames_lock); 772 + kill = net->sysnames; 773 + net->sysnames = sysnames; 774 + write_unlock(&net->sysnames_lock); 775 + } 776 + afs_put_sysnames(kill); 777 + } 778 + 779 + return seq_release(inode, file); 780 + } 781 + 782 + static void *afs_proc_sysname_start(struct seq_file *m, loff_t *pos) 783 + __acquires(&net->sysnames_lock) 784 + { 785 + struct afs_net *net = afs_seq2net(m); 786 + struct afs_sysnames *names = net->sysnames; 787 + 788 + read_lock(&net->sysnames_lock); 789 + 790 + if (*pos >= names->nr) 791 + return NULL; 792 + return (void *)(unsigned long)(*pos + 1); 793 + } 794 + 795 + static void *afs_proc_sysname_next(struct seq_file *m, void *v, loff_t *pos) 796 + { 797 + struct afs_net *net = afs_seq2net(m); 798 + struct afs_sysnames *names = net->sysnames; 799 + 800 + *pos += 1; 801 + if (*pos >= names->nr) 802 + return NULL; 803 + return (void *)(unsigned long)(*pos + 1); 804 + } 805 + 806 + static void afs_proc_sysname_stop(struct seq_file *m, void *v) 807 + __releases(&net->sysnames_lock) 808 + { 809 + struct afs_net *net = afs_seq2net(m); 810 + 811 + read_unlock(&net->sysnames_lock); 812 + } 813 + 814 + static int afs_proc_sysname_show(struct seq_file *m, void *v) 815 + { 816 + struct afs_net *net = afs_seq2net(m); 817 + struct afs_sysnames *sysnames = net->sysnames; 818 + unsigned int i = (unsigned long)v - 1; 819 + 820 + if (i < sysnames->nr) 821 + seq_printf(m, "%s\n", sysnames->subs[i]); 822 + return 0; 823 + } 824 + 825 + /* 826 + * Display general per-net namespace statistics 827 + */ 828 + static int afs_proc_stats_show(struct seq_file *m, void *v) 829 + { 830 + struct afs_net *net = afs_seq2net(m); 831 + 832 + seq_puts(m, "kAFS statistics\n"); 833 + 834 + seq_printf(m, "dir-mgmt: look=%u reval=%u inval=%u relpg=%u\n", 835 + atomic_read(&net->n_lookup), 836 + atomic_read(&net->n_reval), 837 + atomic_read(&net->n_inval), 838 + atomic_read(&net->n_relpg)); 839 + 840 + seq_printf(m, "dir-data: rdpg=%u\n", 841 + atomic_read(&net->n_read_dir)); 842 + 843 + seq_printf(m, "dir-edit: cr=%u rm=%u\n", 844 + atomic_read(&net->n_dir_cr), 845 + atomic_read(&net->n_dir_rm)); 846 + 847 + seq_printf(m, "file-rd : n=%u nb=%lu\n", 848 + atomic_read(&net->n_fetches), 849 + atomic_long_read(&net->n_fetch_bytes)); 850 + seq_printf(m, "file-wr : n=%u nb=%lu\n", 851 + atomic_read(&net->n_stores), 852 + atomic_long_read(&net->n_store_bytes)); 853 + return 0; 854 + } 855 + 856 + /* 857 + * Open "/proc/fs/afs/stats" to allow reading of the stat counters. 858 + */ 859 + static int afs_proc_stats_open(struct inode *inode, struct file *file) 860 + { 861 + return single_open(file, afs_proc_stats_show, NULL); 862 + } 863 + 864 + static const struct file_operations afs_proc_stats_fops = { 865 + .open = afs_proc_stats_open, 866 + .read = seq_read, 867 + .llseek = seq_lseek, 868 + .release = single_release, 869 + };
+1 -1
fs/afs/rotate.c
··· 21 21 /* 22 22 * Initialise a filesystem server cursor for iterating over FS servers. 23 23 */ 24 - void afs_init_fs_cursor(struct afs_fs_cursor *fc, struct afs_vnode *vnode) 24 + static void afs_init_fs_cursor(struct afs_fs_cursor *fc, struct afs_vnode *vnode) 25 25 { 26 26 memset(fc, 0, sizeof(*fc)); 27 27 }
+9
fs/afs/rxrpc.c
··· 926 926 afs_set_call_complete(call, ret, remote_abort); 927 927 return ret; 928 928 } 929 + 930 + /* 931 + * Log protocol error production. 932 + */ 933 + noinline 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 + }
+4 -9
fs/afs/security.c
··· 178 178 } 179 179 } 180 180 181 - if (cb_break != (vnode->cb_break + vnode->cb_interest->server->cb_s_break)) { 182 - rcu_read_unlock(); 181 + if (cb_break != (vnode->cb_break + vnode->cb_interest->server->cb_s_break)) 183 182 goto someone_else_changed_it; 184 - } 185 183 186 184 /* We need a ref on any permits list we want to copy as we'll have to 187 185 * drop the lock to do memory allocation. 188 186 */ 189 - if (permits && !refcount_inc_not_zero(&permits->usage)) { 190 - rcu_read_unlock(); 187 + if (permits && !refcount_inc_not_zero(&permits->usage)) 191 188 goto someone_else_changed_it; 192 - } 193 189 194 190 rcu_read_unlock(); 195 191 ··· 274 278 /* Someone else changed the cache under us - don't recheck at this 275 279 * time. 276 280 */ 281 + rcu_read_unlock(); 277 282 return; 278 283 } 279 284 ··· 292 295 293 296 _enter("{%x:%u},%x", 294 297 vnode->fid.vid, vnode->fid.vnode, key_serial(key)); 295 - 296 - permits = vnode->permit_cache; 297 298 298 299 /* check the permits to see if we've got one yet */ 299 300 if (key == vnode->volume->cell->anonymous_key) { ··· 322 327 */ 323 328 _debug("no valid permit"); 324 329 325 - ret = afs_fetch_status(vnode, key); 330 + ret = afs_fetch_status(vnode, key, false); 326 331 if (ret < 0) { 327 332 *_access = 0; 328 333 _leave(" = %d", ret);
+8 -6
fs/afs/server.c
··· 59 59 alist = rcu_dereference(server->addresses); 60 60 for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) { 61 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 64 if (diff == 0) 64 65 diff = memcmp(&a->sin6_addr, 65 66 &b->sin6_addr, ··· 80 79 alist = rcu_dereference(server->addresses); 81 80 for (i = 0; i < alist->nr_ipv4; i++) { 82 81 b = &alist->addrs[i].transport.sin6; 83 - diff = (u16)a->sin6_port - (u16)b->sin6_port; 82 + diff = ((u16 __force)a->sin6_port - 83 + (u16 __force)b->sin6_port); 84 84 if (diff == 0) 85 - diff = ((u32)a->sin6_addr.s6_addr32[3] - 86 - (u32)b->sin6_addr.s6_addr32[3]); 85 + diff = ((u32 __force)a->sin6_addr.s6_addr32[3] - 86 + (u32 __force)b->sin6_addr.s6_addr32[3]); 87 87 if (diff == 0) 88 88 goto found; 89 89 if (diff < 0) { ··· 383 381 { 384 382 struct afs_server *server = container_of(rcu, struct afs_server, rcu); 385 383 386 - afs_put_addrlist(server->addresses); 384 + afs_put_addrlist(rcu_access_pointer(server->addresses)); 387 385 kfree(server); 388 386 } 389 387 ··· 392 390 */ 393 391 static void afs_destroy_server(struct afs_net *net, struct afs_server *server) 394 392 { 395 - struct afs_addr_list *alist = server->addresses; 393 + struct afs_addr_list *alist = rcu_access_pointer(server->addresses); 396 394 struct afs_addr_cursor ac = { 397 395 .alist = alist, 398 396 .addr = &alist->addrs[0],
+7 -4
fs/afs/super.c
··· 154 154 seq_puts(m, "none"); 155 155 return 0; 156 156 } 157 - 157 + 158 158 switch (volume->type) { 159 159 case AFSVL_RWVOL: 160 160 break; ··· 269 269 int cellnamesz; 270 270 271 271 _enter(",%s", name); 272 - 272 + 273 273 if (!name) { 274 274 printk(KERN_ERR "kAFS: no volume name specified\n"); 275 275 return -EINVAL; ··· 418 418 if (!sb->s_root) 419 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 426 _leave(" = 0"); 424 427 return 0; ··· 679 676 buf->f_bfree = 0; 680 677 return 0; 681 678 } 682 - 679 + 683 680 key = afs_request_key(vnode->volume->cell); 684 681 if (IS_ERR(key)) 685 682 return PTR_ERR(key);
+14 -14
fs/afs/vlclient.c
··· 303 303 r->uuid.clock_seq_hi_and_reserved = htonl(u->clock_seq_hi_and_reserved); 304 304 r->uuid.clock_seq_low = htonl(u->clock_seq_low); 305 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 308 trace_afs_make_vl_call(call); 309 309 return (struct afs_addr_list *)afs_make_call(ac, call, GFP_KERNEL, false); ··· 450 450 call->count2 = ntohl(*bp); /* Type or next count */ 451 451 452 452 if (call->count > YFS_MAXENDPOINTS) 453 - return -EBADMSG; 453 + return afs_protocol_error(call, -EBADMSG); 454 454 455 455 alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT); 456 456 if (!alist) ··· 474 474 size = sizeof(__be32) * (1 + 4 + 1); 475 475 break; 476 476 default: 477 - return -EBADMSG; 477 + return afs_protocol_error(call, -EBADMSG); 478 478 } 479 479 480 480 size += sizeof(__be32); ··· 487 487 switch (call->count2) { 488 488 case YFS_ENDPOINT_IPV4: 489 489 if (ntohl(bp[0]) != sizeof(__be32) * 2) 490 - return -EBADMSG; 490 + return afs_protocol_error(call, -EBADMSG); 491 491 afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2])); 492 492 bp += 3; 493 493 break; 494 494 case YFS_ENDPOINT_IPV6: 495 495 if (ntohl(bp[0]) != sizeof(__be32) * 5) 496 - return -EBADMSG; 496 + return afs_protocol_error(call, -EBADMSG); 497 497 afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5])); 498 498 bp += 6; 499 499 break; 500 500 default: 501 - return -EBADMSG; 501 + return afs_protocol_error(call, -EBADMSG); 502 502 } 503 503 504 504 /* Got either the type of the next entry or the count of 505 505 * volEndpoints if no more fsEndpoints. 506 506 */ 507 - call->count2 = htonl(*bp++); 507 + call->count2 = ntohl(*bp++); 508 508 509 509 call->offset = 0; 510 510 call->count--; ··· 517 517 if (!call->count) 518 518 goto end; 519 519 if (call->count > YFS_MAXENDPOINTS) 520 - return -EBADMSG; 520 + return afs_protocol_error(call, -EBADMSG); 521 521 522 522 call->unmarshall = 3; 523 523 ··· 531 531 return ret; 532 532 533 533 bp = call->buffer; 534 - call->count2 = htonl(*bp++); 534 + call->count2 = ntohl(*bp++); 535 535 call->offset = 0; 536 536 call->unmarshall = 4; 537 537 ··· 545 545 size = sizeof(__be32) * (1 + 4 + 1); 546 546 break; 547 547 default: 548 - return -EBADMSG; 548 + return afs_protocol_error(call, -EBADMSG); 549 549 } 550 550 551 551 if (call->count > 1) ··· 558 558 switch (call->count2) { 559 559 case YFS_ENDPOINT_IPV4: 560 560 if (ntohl(bp[0]) != sizeof(__be32) * 2) 561 - return -EBADMSG; 561 + return afs_protocol_error(call, -EBADMSG); 562 562 bp += 3; 563 563 break; 564 564 case YFS_ENDPOINT_IPV6: 565 565 if (ntohl(bp[0]) != sizeof(__be32) * 5) 566 - return -EBADMSG; 566 + return afs_protocol_error(call, -EBADMSG); 567 567 bp += 6; 568 568 break; 569 569 default: 570 - return -EBADMSG; 570 + return afs_protocol_error(call, -EBADMSG); 571 571 } 572 572 573 573 /* Got either the type of the next entry or the count of ··· 576 576 call->offset = 0; 577 577 call->count--; 578 578 if (call->count > 0) { 579 - call->count2 = htonl(*bp++); 579 + call->count2 = ntohl(*bp++); 580 580 goto again; 581 581 } 582 582
+21 -20
fs/afs/write.c
··· 42 42 if (!req) 43 43 return -ENOMEM; 44 44 45 - atomic_set(&req->usage, 1); 45 + refcount_set(&req->usage, 1); 46 46 req->pos = pos; 47 47 req->len = len; 48 48 req->nr_pages = 1; 49 + req->pages = req->array; 49 50 req->pages[0] = page; 50 51 get_page(page); 51 52 ··· 125 124 page->index, priv); 126 125 goto flush_conflicting_write; 127 126 } 128 - if (to < f || from > t) 127 + /* If the file is being filled locally, allow inter-write 128 + * spaces to be merged into writes. If it's not, only write 129 + * back what the user gives us. 130 + */ 131 + if (!test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags) && 132 + (to < f || from > t)) 129 133 goto flush_conflicting_write; 130 134 if (from < f) 131 135 f = from; ··· 361 355 } 362 356 363 357 switch (ret) { 358 + case 0: 359 + afs_stat_v(vnode, n_stores); 360 + atomic_long_add((last * PAGE_SIZE + to) - 361 + (first * PAGE_SIZE + offset), 362 + &afs_v2net(vnode)->n_store_bytes); 363 + break; 364 364 case -EACCES: 365 365 case -EPERM: 366 366 case -ENOKEY: ··· 424 412 trace_afs_page_dirty(vnode, tracepoint_string("WARN"), 425 413 primary_page->index, priv); 426 414 427 - if (start >= final_page || to < PAGE_SIZE) 415 + if (start >= final_page || 416 + (to < PAGE_SIZE && !test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags))) 428 417 goto no_more; 429 418 430 419 start++; ··· 446 433 } 447 434 448 435 for (loop = 0; loop < n; loop++) { 449 - if (to != PAGE_SIZE) 450 - break; 451 436 page = pages[loop]; 437 + if (to != PAGE_SIZE && 438 + !test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags)) 439 + break; 452 440 if (page->index > final_page) 453 441 break; 454 442 if (!trylock_page(page)) ··· 462 448 priv = page_private(page); 463 449 f = priv & AFS_PRIV_MAX; 464 450 t = priv >> AFS_PRIV_SHIFT; 465 - if (f != 0) { 451 + if (f != 0 && 452 + !test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags)) { 466 453 unlock_page(page); 467 454 break; 468 455 } ··· 747 732 datasync); 748 733 749 734 return file_write_and_wait_range(file, start, end); 750 - } 751 - 752 - /* 753 - * Flush out all outstanding writes on a file opened for writing when it is 754 - * closed. 755 - */ 756 - int afs_flush(struct file *file, fl_owner_t id) 757 - { 758 - _enter(""); 759 - 760 - if ((file->f_mode & FMODE_WRITE) == 0) 761 - return 0; 762 - 763 - return vfs_fsync(file, 0); 764 735 } 765 736 766 737 /*
+103
fs/afs/xdr_fs.h
··· 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 + 15 + struct 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 + */ 54 + union 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 + */ 72 + struct 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 + */ 84 + union 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 + */ 99 + struct afs_xdr_dir_page { 100 + union afs_xdr_dir_block blocks[AFS_DIR_BLOCKS_PER_PAGE]; 101 + }; 102 + 103 + #endif /* XDR_FS_H */
+1 -1
include/linux/fs.h
··· 1667 1667 unsigned); 1668 1668 1669 1669 struct dir_context { 1670 - const filldir_t actor; 1670 + filldir_t actor; 1671 1671 loff_t pos; 1672 1672 }; 1673 1673
+113
include/trace/events/afs.h
··· 49 49 afs_FS_ExtendLock = 157, /* AFS Extend a file lock */ 50 50 afs_FS_ReleaseLock = 158, /* AFS Release a file lock */ 51 51 afs_FS_Lookup = 161, /* AFS lookup file in directory */ 52 + afs_FS_InlineBulkStatus = 65536, /* AFS Fetch multiple file statuses with errors */ 52 53 afs_FS_FetchData64 = 65537, /* AFS Fetch file data */ 53 54 afs_FS_StoreData64 = 65538, /* AFS Store file data */ 54 55 afs_FS_GiveUpAllCallBacks = 65539, /* AFS Give up all our callbacks on a server */ ··· 61 60 afs_VL_GetAddrsU = 533, /* AFS Get FS server addresses */ 62 61 afs_YFSVL_GetEndpoints = 64002, /* YFS Get FS & Vol server addresses */ 63 62 afs_VL_GetCapabilities = 65537, /* AFS Get VL server capabilities */ 63 + }; 64 + 65 + enum afs_edit_dir_op { 66 + afs_edit_dir_create, 67 + afs_edit_dir_create_error, 68 + afs_edit_dir_create_inval, 69 + afs_edit_dir_create_nospc, 70 + afs_edit_dir_delete, 71 + afs_edit_dir_delete_error, 72 + afs_edit_dir_delete_inval, 73 + afs_edit_dir_delete_noent, 74 + }; 75 + 76 + enum afs_edit_dir_reason { 77 + afs_edit_dir_for_create, 78 + afs_edit_dir_for_link, 79 + afs_edit_dir_for_mkdir, 80 + afs_edit_dir_for_rename, 81 + afs_edit_dir_for_rmdir, 82 + afs_edit_dir_for_symlink, 83 + afs_edit_dir_for_unlink, 64 84 }; 65 85 66 86 #endif /* end __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY */ ··· 115 93 EM(afs_FS_ExtendLock, "FS.ExtendLock") \ 116 94 EM(afs_FS_ReleaseLock, "FS.ReleaseLock") \ 117 95 EM(afs_FS_Lookup, "FS.Lookup") \ 96 + EM(afs_FS_InlineBulkStatus, "FS.InlineBulkStatus") \ 118 97 EM(afs_FS_FetchData64, "FS.FetchData64") \ 119 98 EM(afs_FS_StoreData64, "FS.StoreData64") \ 120 99 EM(afs_FS_GiveUpAllCallBacks, "FS.GiveUpAllCallBacks") \ ··· 126 103 EM(afs_VL_GetAddrsU, "VL.GetAddrsU") \ 127 104 EM(afs_YFSVL_GetEndpoints, "YFSVL.GetEndpoints") \ 128 105 E_(afs_VL_GetCapabilities, "VL.GetCapabilities") 106 + 107 + #define afs_edit_dir_ops \ 108 + EM(afs_edit_dir_create, "create") \ 109 + EM(afs_edit_dir_create_error, "c_fail") \ 110 + EM(afs_edit_dir_create_inval, "c_invl") \ 111 + EM(afs_edit_dir_create_nospc, "c_nspc") \ 112 + EM(afs_edit_dir_delete, "delete") \ 113 + EM(afs_edit_dir_delete_error, "d_err ") \ 114 + EM(afs_edit_dir_delete_inval, "d_invl") \ 115 + E_(afs_edit_dir_delete_noent, "d_nent") 116 + 117 + #define afs_edit_dir_reasons \ 118 + EM(afs_edit_dir_for_create, "Create") \ 119 + EM(afs_edit_dir_for_link, "Link ") \ 120 + EM(afs_edit_dir_for_mkdir, "MkDir ") \ 121 + EM(afs_edit_dir_for_rename, "Rename") \ 122 + EM(afs_edit_dir_for_rmdir, "RmDir ") \ 123 + EM(afs_edit_dir_for_symlink, "Symlnk") \ 124 + E_(afs_edit_dir_for_unlink, "Unlink") 129 125 130 126 131 127 /* ··· 158 116 afs_call_traces; 159 117 afs_fs_operations; 160 118 afs_vl_operations; 119 + afs_edit_dir_ops; 120 + afs_edit_dir_reasons; 161 121 162 122 /* 163 123 * Now redefine the EM() and E_() macros to map the enums to the strings that ··· 504 460 __entry->call, 505 461 __entry->from, __entry->to, 506 462 __entry->ret, __entry->abort) 463 + ); 464 + 465 + TRACE_EVENT(afs_edit_dir, 466 + TP_PROTO(struct afs_vnode *dvnode, 467 + enum afs_edit_dir_reason why, 468 + enum afs_edit_dir_op op, 469 + unsigned int block, 470 + unsigned int slot, 471 + unsigned int f_vnode, 472 + unsigned int f_unique, 473 + const char *name), 474 + 475 + TP_ARGS(dvnode, why, op, block, slot, f_vnode, f_unique, name), 476 + 477 + TP_STRUCT__entry( 478 + __field(unsigned int, vnode ) 479 + __field(unsigned int, unique ) 480 + __field(enum afs_edit_dir_reason, why ) 481 + __field(enum afs_edit_dir_op, op ) 482 + __field(unsigned int, block ) 483 + __field(unsigned short, slot ) 484 + __field(unsigned int, f_vnode ) 485 + __field(unsigned int, f_unique ) 486 + __array(char, name, 18 ) 487 + ), 488 + 489 + TP_fast_assign( 490 + int __len = strlen(name); 491 + __len = min(__len, 17); 492 + __entry->vnode = dvnode->fid.vnode; 493 + __entry->unique = dvnode->fid.unique; 494 + __entry->why = why; 495 + __entry->op = op; 496 + __entry->block = block; 497 + __entry->slot = slot; 498 + __entry->f_vnode = f_vnode; 499 + __entry->f_unique = f_unique; 500 + memcpy(__entry->name, name, __len); 501 + __entry->name[__len] = 0; 502 + ), 503 + 504 + TP_printk("d=%x:%x %s %s %u[%u] f=%x:%x %s", 505 + __entry->vnode, __entry->unique, 506 + __print_symbolic(__entry->why, afs_edit_dir_reasons), 507 + __print_symbolic(__entry->op, afs_edit_dir_ops), 508 + __entry->block, __entry->slot, 509 + __entry->f_vnode, __entry->f_unique, 510 + __entry->name) 511 + ); 512 + 513 + TRACE_EVENT(afs_protocol_error, 514 + TP_PROTO(struct afs_call *call, int error, const void *where), 515 + 516 + TP_ARGS(call, error, where), 517 + 518 + TP_STRUCT__entry( 519 + __field(unsigned int, call ) 520 + __field(int, error ) 521 + __field(const void *, where ) 522 + ), 523 + 524 + TP_fast_assign( 525 + __entry->call = call ? call->debug_id : 0; 526 + __entry->error = error; 527 + __entry->where = where; 528 + ), 529 + 530 + TP_printk("c=%08x r=%d sp=%pSR", 531 + __entry->call, __entry->error, __entry->where) 507 532 ); 508 533 509 534 #endif /* _TRACE_AFS_H */