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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'nfs-for-4.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes and cleanups from Trond Myklebust:
"Bugfixes:
- pNFS/flexfiles: Fix an XDR encoding bug in layoutreturn
- pNFS/flexfiles: Improve merging of errors in LAYOUTRETURN

Cleanups:
- NFS: Simplify nfs_request_add_commit_list() arguments"

* tag 'nfs-for-4.5-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
pNFS/flexfiles: Fix an XDR encoding bug in layoutreturn
NFS: Simplify nfs_request_add_commit_list() arguments
pNFS/flexfiles: Improve merging of errors in LAYOUTRETURN

+46 -68
+1 -1
fs/nfs/filelayout/filelayout.c
··· 971 971 u32 i, j; 972 972 973 973 if (fl->commit_through_mds) { 974 - nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo); 974 + nfs_request_add_commit_list(req, cinfo); 975 975 } else { 976 976 /* Note that we are calling nfs4_fl_calc_j_index on each page 977 977 * that ends up being committed to a data server. An attractive
+2 -4
fs/nfs/flexfilelayout/flexfilelayout.c
··· 1948 1948 start = xdr_reserve_space(xdr, 4); 1949 1949 BUG_ON(!start); 1950 1950 1951 - if (ff_layout_encode_ioerr(flo, xdr, args)) 1952 - goto out; 1953 - 1951 + ff_layout_encode_ioerr(flo, xdr, args); 1954 1952 ff_layout_encode_iostats(flo, xdr, args); 1955 - out: 1953 + 1956 1954 *start = cpu_to_be32((xdr->p - start - 1) * 4); 1957 1955 dprintk("%s: Return\n", __func__); 1958 1956 }
+39 -58
fs/nfs/flexfilelayout/flexfilelayoutdev.c
··· 218 218 err->length = end - err->offset; 219 219 } 220 220 221 - static bool ds_error_can_merge(struct nfs4_ff_layout_ds_err *err, u64 offset, 222 - u64 length, int status, enum nfs_opnum4 opnum, 223 - nfs4_stateid *stateid, 224 - struct nfs4_deviceid *deviceid) 221 + static int 222 + ff_ds_error_match(const struct nfs4_ff_layout_ds_err *e1, 223 + const struct nfs4_ff_layout_ds_err *e2) 225 224 { 226 - return err->status == status && err->opnum == opnum && 227 - nfs4_stateid_match(&err->stateid, stateid) && 228 - !memcmp(&err->deviceid, deviceid, sizeof(*deviceid)) && 229 - end_offset(err->offset, err->length) >= offset && 230 - err->offset <= end_offset(offset, length); 225 + int ret; 226 + 227 + if (e1->opnum != e2->opnum) 228 + return e1->opnum < e2->opnum ? -1 : 1; 229 + if (e1->status != e2->status) 230 + return e1->status < e2->status ? -1 : 1; 231 + ret = memcmp(&e1->stateid, &e2->stateid, sizeof(e1->stateid)); 232 + if (ret != 0) 233 + return ret; 234 + ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid)); 235 + if (ret != 0) 236 + return ret; 237 + if (end_offset(e1->offset, e1->length) < e2->offset) 238 + return -1; 239 + if (e1->offset > end_offset(e2->offset, e2->length)) 240 + return 1; 241 + /* If ranges overlap or are contiguous, they are the same */ 242 + return 0; 231 243 } 232 244 233 - static bool merge_ds_error(struct nfs4_ff_layout_ds_err *old, 234 - struct nfs4_ff_layout_ds_err *new) 235 - { 236 - if (!ds_error_can_merge(old, new->offset, new->length, new->status, 237 - new->opnum, &new->stateid, &new->deviceid)) 238 - return false; 239 - 240 - extend_ds_error(old, new->offset, new->length); 241 - return true; 242 - } 243 - 244 - static bool 245 + static void 245 246 ff_layout_add_ds_error_locked(struct nfs4_flexfile_layout *flo, 246 247 struct nfs4_ff_layout_ds_err *dserr) 247 248 { 248 - struct nfs4_ff_layout_ds_err *err; 249 + struct nfs4_ff_layout_ds_err *err, *tmp; 250 + struct list_head *head = &flo->error_list; 251 + int match; 249 252 250 - list_for_each_entry(err, &flo->error_list, list) { 251 - if (merge_ds_error(err, dserr)) { 252 - return true; 253 - } 254 - } 255 - 256 - list_add(&dserr->list, &flo->error_list); 257 - return false; 258 - } 259 - 260 - static bool 261 - ff_layout_update_ds_error(struct nfs4_flexfile_layout *flo, u64 offset, 262 - u64 length, int status, enum nfs_opnum4 opnum, 263 - nfs4_stateid *stateid, struct nfs4_deviceid *deviceid) 264 - { 265 - bool found = false; 266 - struct nfs4_ff_layout_ds_err *err; 267 - 268 - list_for_each_entry(err, &flo->error_list, list) { 269 - if (ds_error_can_merge(err, offset, length, status, opnum, 270 - stateid, deviceid)) { 271 - found = true; 272 - extend_ds_error(err, offset, length); 253 + /* Do insertion sort w/ merges */ 254 + list_for_each_entry_safe(err, tmp, &flo->error_list, list) { 255 + match = ff_ds_error_match(err, dserr); 256 + if (match < 0) 257 + continue; 258 + if (match > 0) { 259 + /* Add entry "dserr" _before_ entry "err" */ 260 + head = &err->list; 273 261 break; 274 262 } 263 + /* Entries match, so merge "err" into "dserr" */ 264 + extend_ds_error(dserr, err->offset, err->length); 265 + list_del(&err->list); 266 + kfree(err); 275 267 } 276 268 277 - return found; 269 + list_add_tail(&dserr->list, head); 278 270 } 279 271 280 272 int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo, ··· 275 283 gfp_t gfp_flags) 276 284 { 277 285 struct nfs4_ff_layout_ds_err *dserr; 278 - bool needfree; 279 286 280 287 if (status == 0) 281 288 return 0; ··· 282 291 if (mirror->mirror_ds == NULL) 283 292 return -EINVAL; 284 293 285 - spin_lock(&flo->generic_hdr.plh_inode->i_lock); 286 - if (ff_layout_update_ds_error(flo, offset, length, status, opnum, 287 - &mirror->stateid, 288 - &mirror->mirror_ds->id_node.deviceid)) { 289 - spin_unlock(&flo->generic_hdr.plh_inode->i_lock); 290 - return 0; 291 - } 292 - spin_unlock(&flo->generic_hdr.plh_inode->i_lock); 293 294 dserr = kmalloc(sizeof(*dserr), gfp_flags); 294 295 if (!dserr) 295 296 return -ENOMEM; ··· 296 313 NFS4_DEVICEID4_SIZE); 297 314 298 315 spin_lock(&flo->generic_hdr.plh_inode->i_lock); 299 - needfree = ff_layout_add_ds_error_locked(flo, dserr); 316 + ff_layout_add_ds_error_locked(flo, dserr); 300 317 spin_unlock(&flo->generic_hdr.plh_inode->i_lock); 301 - if (needfree) 302 - kfree(dserr); 303 318 304 319 return 0; 305 320 }
+1 -1
fs/nfs/internal.h
··· 484 484 struct nfs_commit_info *cinfo, 485 485 u32 ds_commit_idx); 486 486 void nfs_commitdata_release(struct nfs_commit_data *data); 487 - void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst, 487 + void nfs_request_add_commit_list(struct nfs_page *req, 488 488 struct nfs_commit_info *cinfo); 489 489 void nfs_request_add_commit_list_locked(struct nfs_page *req, 490 490 struct list_head *dst,
+3 -4
fs/nfs/write.c
··· 830 830 * holding the nfs_page lock. 831 831 */ 832 832 void 833 - nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst, 834 - struct nfs_commit_info *cinfo) 833 + nfs_request_add_commit_list(struct nfs_page *req, struct nfs_commit_info *cinfo) 835 834 { 836 835 spin_lock(cinfo->lock); 837 - nfs_request_add_commit_list_locked(req, dst, cinfo); 836 + nfs_request_add_commit_list_locked(req, &cinfo->mds->list, cinfo); 838 837 spin_unlock(cinfo->lock); 839 838 nfs_mark_page_unstable(req->wb_page, cinfo); 840 839 } ··· 891 892 { 892 893 if (pnfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx)) 893 894 return; 894 - nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo); 895 + nfs_request_add_commit_list(req, cinfo); 895 896 } 896 897 897 898 static void