From 21051ba6259c519e20a7d575ddceb16e84ad2a5d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 14 May 2007 16:50:44 -0400 Subject: NLM: Fix locking client timeouts... nlmsvc_timeout is already in units of HZ... Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/lockd/host.c b/fs/lockd/host.c index ad21c07..96070bf 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -221,7 +221,7 @@ nlm_bind_host(struct nlm_host *host) host->h_nextrebind - jiffies); } } else { - unsigned long increment = nlmsvc_timeout * HZ; + unsigned long increment = nlmsvc_timeout; struct rpc_timeout timeparms = { .to_initval = increment, .to_increment = increment, -- cgit v1.1 From 550facd138d8f6b0ca683c1e894b5cd0f381cb63 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Thu, 10 May 2007 22:55:07 -0700 Subject: NLM: don't use CLONE_SIGHAND in nlmclnt_recovery reclaimer() calls allow_signal() which plays with parent process's ->sighand. Signed-off-by: Oleg Nesterov Cc: Trond Myklebust Cc: "J. Bruce Fields" Cc: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Trond Myklebust --- fs/lockd/clntlock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index f4d45d4..d070b18 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -153,7 +153,7 @@ nlmclnt_recovery(struct nlm_host *host) if (!host->h_reclaiming++) { nlm_get_host(host); __module_get(THIS_MODULE); - if (kernel_thread(reclaimer, host, CLONE_KERNEL) < 0) + if (kernel_thread(reclaimer, host, CLONE_FS | CLONE_FILES) < 0) module_put(THIS_MODULE); } } -- cgit v1.1 From 60945cb7c8377b727288275f21791914fe65311c Mon Sep 17 00:00:00 2001 From: Nate Diller Date: Thu, 10 May 2007 22:55:08 -0700 Subject: NFS: use zero_user_page Use zero_user_page() instead of the newly deprecated memclear_highpage_flush(). Signed-off-by: Nate Diller Cc: Trond Myklebust Cc: "J. Bruce Fields" Signed-off-by: Andrew Morton Signed-off-by: Trond Myklebust --- fs/nfs/read.c | 10 +++++----- fs/nfs/write.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'fs') diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 9a55807..7bd7cb9 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -79,7 +79,7 @@ void nfs_readdata_release(void *data) static int nfs_return_empty_page(struct page *page) { - memclear_highpage_flush(page, 0, PAGE_CACHE_SIZE); + zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); SetPageUptodate(page); unlock_page(page); return 0; @@ -103,10 +103,10 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data) pglen = PAGE_CACHE_SIZE - base; for (;;) { if (remainder <= pglen) { - memclear_highpage_flush(*pages, base, remainder); + zero_user_page(*pages, base, remainder, KM_USER0); break; } - memclear_highpage_flush(*pages, base, pglen); + zero_user_page(*pages, base, pglen, KM_USER0); pages++; remainder -= pglen; pglen = PAGE_CACHE_SIZE; @@ -130,7 +130,7 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, return PTR_ERR(new); } if (len < PAGE_CACHE_SIZE) - memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); + zero_user_page(page, len, PAGE_CACHE_SIZE - len, KM_USER0); nfs_list_add_request(new, &one_request); if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE) @@ -532,7 +532,7 @@ readpage_async_filler(void *data, struct page *page) return PTR_ERR(new); } if (len < PAGE_CACHE_SIZE) - memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); + zero_user_page(page, len, PAGE_CACHE_SIZE - len, KM_USER0); nfs_pageio_add_request(desc->pgio, new); return 0; } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index de92b95..211d0b1 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -168,7 +168,7 @@ static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int if (count != nfs_page_length(page)) return; if (count != PAGE_CACHE_SIZE) - memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count); + zero_user_page(page, count, PAGE_CACHE_SIZE - count, KM_USER0); SetPageUptodate(page); } -- cgit v1.1 From 8ae20abdd18c6c7f21bbae931353e7cfad77d7b6 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 14 May 2007 16:50:45 -0400 Subject: NFS4: Fix incorrect use of sizeof() in fs/nfs/nfs4xdr.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The XDR code should not depend on the physical allocation size of structures like nfs4_stateid and nfs4_verifier since those may have to change at some future date. We therefore replace all uses of sizeof() with constants like NFS4_VERIFIER_SIZE and NFS4_STATEID_SIZE. This also has the side-effect of fixing some warnings of the type format ‘%u’ expects type ‘unsigned int’, but argument X has type ‘long unsigned int’ on 64-bit systems Signed-off-by: Trond Myklebust --- fs/nfs/nfs4xdr.c | 90 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) (limited to 'fs') diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 938f371..a57eacf 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -646,10 +646,10 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg) { __be32 *p; - RESERVE_SPACE(8+sizeof(arg->stateid->data)); + RESERVE_SPACE(8+NFS4_STATEID_SIZE); WRITE32(OP_CLOSE); WRITE32(arg->seqid->sequence->counter); - WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data)); + WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); return 0; } @@ -793,17 +793,17 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args) WRITE64(nfs4_lock_length(args->fl)); WRITE32(args->new_lock_owner); if (args->new_lock_owner){ - RESERVE_SPACE(40); + RESERVE_SPACE(4+NFS4_STATEID_SIZE+20); WRITE32(args->open_seqid->sequence->counter); - WRITEMEM(args->open_stateid->data, sizeof(args->open_stateid->data)); + WRITEMEM(args->open_stateid->data, NFS4_STATEID_SIZE); WRITE32(args->lock_seqid->sequence->counter); WRITE64(args->lock_owner.clientid); WRITE32(4); WRITE32(args->lock_owner.id); } else { - RESERVE_SPACE(20); - WRITEMEM(args->lock_stateid->data, sizeof(args->lock_stateid->data)); + RESERVE_SPACE(NFS4_STATEID_SIZE+4); + WRITEMEM(args->lock_stateid->data, NFS4_STATEID_SIZE); WRITE32(args->lock_seqid->sequence->counter); } @@ -830,11 +830,11 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *arg { __be32 *p; - RESERVE_SPACE(44); + RESERVE_SPACE(12+NFS4_STATEID_SIZE+16); WRITE32(OP_LOCKU); WRITE32(nfs4_lock_type(args->fl, 0)); WRITE32(args->seqid->sequence->counter); - WRITEMEM(args->stateid->data, sizeof(args->stateid->data)); + WRITEMEM(args->stateid->data, NFS4_STATEID_SIZE); WRITE64(args->fl->fl_start); WRITE64(nfs4_lock_length(args->fl)); @@ -966,9 +966,9 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struc { __be32 *p; - RESERVE_SPACE(4+sizeof(stateid->data)); + RESERVE_SPACE(4+NFS4_STATEID_SIZE); WRITE32(NFS4_OPEN_CLAIM_DELEGATE_CUR); - WRITEMEM(stateid->data, sizeof(stateid->data)); + WRITEMEM(stateid->data, NFS4_STATEID_SIZE); encode_string(xdr, name->len, name->name); } @@ -996,9 +996,9 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con { __be32 *p; - RESERVE_SPACE(8+sizeof(arg->stateid->data)); + RESERVE_SPACE(4+NFS4_STATEID_SIZE+4); WRITE32(OP_OPEN_CONFIRM); - WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data)); + WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); WRITE32(arg->seqid->sequence->counter); return 0; @@ -1008,9 +1008,9 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea { __be32 *p; - RESERVE_SPACE(8+sizeof(arg->stateid->data)); + RESERVE_SPACE(4+NFS4_STATEID_SIZE+4); WRITE32(OP_OPEN_DOWNGRADE); - WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data)); + WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE); WRITE32(arg->seqid->sequence->counter); encode_share_access(xdr, arg->open_flags); return 0; @@ -1045,12 +1045,12 @@ static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context nfs4_stateid stateid; __be32 *p; - RESERVE_SPACE(16); + RESERVE_SPACE(NFS4_STATEID_SIZE); if (ctx->state != NULL) { nfs4_copy_stateid(&stateid, ctx->state, ctx->lockowner); - WRITEMEM(stateid.data, sizeof(stateid.data)); + WRITEMEM(stateid.data, NFS4_STATEID_SIZE); } else - WRITEMEM(zero_stateid.data, sizeof(zero_stateid.data)); + WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE); } static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args) @@ -1079,10 +1079,10 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg int replen; __be32 *p; - RESERVE_SPACE(32+sizeof(nfs4_verifier)); + RESERVE_SPACE(12+NFS4_VERIFIER_SIZE+20); WRITE32(OP_READDIR); WRITE64(readdir->cookie); - WRITEMEM(readdir->verifier.data, sizeof(readdir->verifier.data)); + WRITEMEM(readdir->verifier.data, NFS4_VERIFIER_SIZE); WRITE32(readdir->count >> 1); /* We're not doing readdirplus */ WRITE32(readdir->count); WRITE32(2); @@ -1190,9 +1190,9 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg) { __be32 *p; - RESERVE_SPACE(4+sizeof(zero_stateid.data)); + RESERVE_SPACE(4+NFS4_STATEID_SIZE); WRITE32(OP_SETATTR); - WRITEMEM(zero_stateid.data, sizeof(zero_stateid.data)); + WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE); RESERVE_SPACE(2*4); WRITE32(1); WRITE32(FATTR4_WORD0_ACL); @@ -1220,9 +1220,9 @@ static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs * int status; __be32 *p; - RESERVE_SPACE(4+sizeof(arg->stateid.data)); + RESERVE_SPACE(4+NFS4_STATEID_SIZE); WRITE32(OP_SETATTR); - WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); + WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE); if ((status = encode_attrs(xdr, arg->iap, server))) return status; @@ -1234,9 +1234,9 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclien { __be32 *p; - RESERVE_SPACE(4 + sizeof(setclientid->sc_verifier->data)); + RESERVE_SPACE(4 + NFS4_VERIFIER_SIZE); WRITE32(OP_SETCLIENTID); - WRITEMEM(setclientid->sc_verifier->data, sizeof(setclientid->sc_verifier->data)); + WRITEMEM(setclientid->sc_verifier->data, NFS4_VERIFIER_SIZE); encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name); RESERVE_SPACE(4); @@ -1253,10 +1253,10 @@ static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_c { __be32 *p; - RESERVE_SPACE(12 + sizeof(client_state->cl_confirm.data)); + RESERVE_SPACE(12 + NFS4_VERIFIER_SIZE); WRITE32(OP_SETCLIENTID_CONFIRM); WRITE64(client_state->cl_clientid); - WRITEMEM(client_state->cl_confirm.data, sizeof(client_state->cl_confirm.data)); + WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE); return 0; } @@ -1284,10 +1284,10 @@ static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *statei { __be32 *p; - RESERVE_SPACE(20); + RESERVE_SPACE(4+NFS4_STATEID_SIZE); WRITE32(OP_DELEGRETURN); - WRITEMEM(stateid->data, sizeof(stateid->data)); + WRITEMEM(stateid->data, NFS4_STATEID_SIZE); return 0; } @@ -2897,8 +2897,8 @@ static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res) status = decode_op_hdr(xdr, OP_CLOSE); if (status) return status; - READ_BUF(sizeof(res->stateid.data)); - COPYMEM(res->stateid.data, sizeof(res->stateid.data)); + READ_BUF(NFS4_STATEID_SIZE); + COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); return 0; } @@ -3186,8 +3186,8 @@ static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) status = decode_op_hdr(xdr, OP_LOCK); if (status == 0) { - READ_BUF(sizeof(res->stateid.data)); - COPYMEM(res->stateid.data, sizeof(res->stateid.data)); + READ_BUF(NFS4_STATEID_SIZE); + COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); } else if (status == -NFS4ERR_DENIED) return decode_lock_denied(xdr, NULL); return status; @@ -3209,8 +3209,8 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res) status = decode_op_hdr(xdr, OP_LOCKU); if (status == 0) { - READ_BUF(sizeof(res->stateid.data)); - COPYMEM(res->stateid.data, sizeof(res->stateid.data)); + READ_BUF(NFS4_STATEID_SIZE); + COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); } return status; } @@ -3251,8 +3251,8 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) res->delegation_type = 0; return 0; } - READ_BUF(20); - COPYMEM(res->delegation.data, sizeof(res->delegation.data)); + READ_BUF(NFS4_STATEID_SIZE+4); + COPYMEM(res->delegation.data, NFS4_STATEID_SIZE); READ32(res->do_recall); switch (delegation_type) { case NFS4_OPEN_DELEGATE_READ: @@ -3275,8 +3275,8 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) status = decode_op_hdr(xdr, OP_OPEN); if (status) return status; - READ_BUF(sizeof(res->stateid.data)); - COPYMEM(res->stateid.data, sizeof(res->stateid.data)); + READ_BUF(NFS4_STATEID_SIZE); + COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); decode_change_info(xdr, &res->cinfo); @@ -3302,8 +3302,8 @@ static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmre status = decode_op_hdr(xdr, OP_OPEN_CONFIRM); if (status) return status; - READ_BUF(sizeof(res->stateid.data)); - COPYMEM(res->stateid.data, sizeof(res->stateid.data)); + READ_BUF(NFS4_STATEID_SIZE); + COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); return 0; } @@ -3315,8 +3315,8 @@ static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *re status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE); if (status) return status; - READ_BUF(sizeof(res->stateid.data)); - COPYMEM(res->stateid.data, sizeof(res->stateid.data)); + READ_BUF(NFS4_STATEID_SIZE); + COPYMEM(res->stateid.data, NFS4_STATEID_SIZE); return 0; } @@ -3590,9 +3590,9 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) } READ32(nfserr); if (nfserr == NFS_OK) { - READ_BUF(8 + sizeof(clp->cl_confirm.data)); + READ_BUF(8 + NFS4_VERIFIER_SIZE); READ64(clp->cl_clientid); - COPYMEM(clp->cl_confirm.data, sizeof(clp->cl_confirm.data)); + COPYMEM(clp->cl_confirm.data, NFS4_VERIFIER_SIZE); } else if (nfserr == NFSERR_CLID_INUSE) { uint32_t len; -- cgit v1.1 From 10afec9081fee7e48995fa396fba22c7de4b99d4 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 14 May 2007 17:16:04 -0400 Subject: NFS: Fix some 'sparse' warnings... - fs/nfs/dir.c:610:8: warning: symbol 'nfs_llseek_dir' was not declared. Should it be static? - fs/nfs/dir.c:636:5: warning: symbol 'nfs_fsync_dir' was not declared. Should it be static? - fs/nfs/write.c:925:19: warning: symbol 'req' shadows an earlier one - fs/nfs/write.c:61:6: warning: symbol 'nfs_commit_rcu_free' was not declared. Should it be static? - fs/nfs/nfs4proc.c:793:5: warning: symbol 'nfs4_recover_expired_lease' was not declared. Should it be static? Signed-off-by: Trond Myklebust --- fs/nfs/delegation.c | 2 +- fs/nfs/dir.c | 4 ++-- fs/nfs/nfs4proc.c | 4 ++-- fs/nfs/nfs4state.c | 2 +- fs/nfs/write.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'fs') diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 841c99a..7f37d1b 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -226,7 +226,7 @@ restart: spin_unlock(&clp->cl_lock); } -int nfs_do_expire_all_delegations(void *ptr) +static int nfs_do_expire_all_delegations(void *ptr) { struct nfs_client *clp = ptr; struct nfs_delegation *delegation; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 3df4288..ac92e45 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -607,7 +607,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) return res; } -loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) +static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin) { mutex_lock(&filp->f_path.dentry->d_inode->i_mutex); switch (origin) { @@ -633,7 +633,7 @@ out: * All directory operations under NFS are synchronous, so fsync() * is a dummy operation. */ -int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync) +static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync) { dfprintk(VFS, "NFS: fsync_dir(%s/%s) datasync %d\n", dentry->d_parent->d_name.name, dentry->d_name.name, diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index d6a30e9..648e0ac 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -790,7 +790,7 @@ out: return -EACCES; } -int nfs4_recover_expired_lease(struct nfs_server *server) +static int nfs4_recover_expired_lease(struct nfs_server *server) { struct nfs_client *clp = server->nfs_client; int ret; @@ -2748,7 +2748,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) /* This is the error handling routine for processes that are allowed * to sleep. */ -int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) +static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) { struct nfs_client *clp = server->nfs_client; int ret = errorcode; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 5fffbdf..8ed79d5 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -104,7 +104,7 @@ struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp) return cred; } -struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp) +static struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp) { struct nfs4_state_owner *sp; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 211d0b1..b084c03 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -58,7 +58,7 @@ struct nfs_write_data *nfs_commit_alloc(void) return p; } -void nfs_commit_rcu_free(struct rcu_head *head) +static void nfs_commit_rcu_free(struct rcu_head *head) { struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); if (p && (p->pagevec != &p->page_array[0])) @@ -922,7 +922,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i return 0; out_bad: while (!list_empty(head)) { - struct nfs_page *req = nfs_list_entry(head->next); + req = nfs_list_entry(head->next); nfs_list_remove_request(req); nfs_redirty_request(req); nfs_end_page_writeback(req->wb_page); -- cgit v1.1 From 2e42c3e2aec6e24e58c4c601e1a33f0e9e36e314 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 14 May 2007 17:20:41 -0400 Subject: NFS: Fix more sparse warnings - fs/nfs/nfs4xdr.c:2499:42: warning: incorrect type in argument 2 (different signedness) - fs/nfs/nfs4xdr.c:2658:49: warning: incorrect type in argument 4 (different explicit signedness) - fs/nfs/nfs4xdr.c:2683:50: warning: incorrect type in argument 4 (different explicit signedness) - fs/nfs/nfs4xdr.c:3063:68: warning: incorrect type in argument 4 (different explicit signedness) - fs/nfs/nfs4xdr.c:3065:68: warning: incorrect type in argument 4 (different explicit signedness) - fs/nfs/callback_xdr.c:138:31: warning: incorrect type in argument 2 (different signedness) Signed-off-by: Trond Myklebust --- fs/nfs/callback.h | 4 ++-- fs/nfs/nfs4xdr.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'fs') diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index db3d791..c2bb14e 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h @@ -24,7 +24,7 @@ enum nfs4_callback_opnum { }; struct cb_compound_hdr_arg { - int taglen; + unsigned int taglen; const char *tag; unsigned int callback_ident; unsigned nops; @@ -32,7 +32,7 @@ struct cb_compound_hdr_arg { struct cb_compound_hdr_res { __be32 *status; - int taglen; + unsigned int taglen; const char *tag; __be32 *nops; }; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index a57eacf..8003c91 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -2494,7 +2494,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st int i; dprintk("%s: using first %d of %d servers returned for location %d\n", __FUNCTION__, NFS4_FS_LOCATION_MAXSERVERS, m, res->nlocations); for (i = loc->nservers; i < m; i++) { - int len; + unsigned int len; char *data; status = decode_opaque_inline(xdr, &len, &data); if (unlikely(status != 0)) @@ -2642,7 +2642,7 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t return 0; } -static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *uid) +static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *uid) { uint32_t len; __be32 *p; @@ -2667,7 +2667,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf return 0; } -static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *gid) +static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *gid) { uint32_t len; __be32 *p; -- cgit v1.1 From d48c5f41000ad176df71d2d43932c6c50f938196 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 14 May 2007 17:21:26 -0400 Subject: NLM: Fix sparse warnings - fs/lockd/xdr4.c:140:27: warning: incorrect type in argument 2 (different explicit signedness) - fs/lockd/xdr4.c:141:27: warning: incorrect type in argument 2 (different explicit signedness) - fs/lockd/xdr4.c:432:28: warning: incorrect type in argument 2 (different explicit signedness) - fs/lockd/xdr4.c:433:28: warning: incorrect type in argument 2 (different explicit signedness) - fs/lockd/xdr4.c:587:20: warning: symbol 'nlm_version4' was not declared. Should it be static? Signed-off-by: Trond Myklebust --- fs/lockd/xdr.c | 4 ---- fs/lockd/xdr4.c | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'fs') diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 9702956..5316e30 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -586,10 +586,6 @@ static struct rpc_version nlm_version3 = { .procs = nlm_procedures, }; -#ifdef CONFIG_LOCKD_V4 -extern struct rpc_version nlm_version4; -#endif - static struct rpc_version * nlm_versions[] = { [1] = &nlm_version1, [3] = &nlm_version3, diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index ce1efdb..846fc1d 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c @@ -123,7 +123,8 @@ static __be32 * nlm4_decode_lock(__be32 *p, struct nlm_lock *lock) { struct file_lock *fl = &lock->fl; - __s64 len, start, end; + __u64 len, start; + __s64 end; if (!(p = xdr_decode_string_inplace(p, &lock->caller, &lock->len, NLM_MAXSTRLEN)) @@ -417,7 +418,8 @@ nlm4clt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) if (resp->status == nlm_lck_denied) { struct file_lock *fl = &resp->lock.fl; u32 excl; - s64 start, end, len; + __u64 start, len; + __s64 end; memset(&resp->lock, 0, sizeof(resp->lock)); locks_init_lock(fl); -- cgit v1.1 From faab83bbcd9e001077e42a7c085f1e871997647f Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 15 May 2007 23:57:02 -0700 Subject: AFS: write back dirty data on unmount Fix AFS to write back dirty on unmounting. This didn't happen because afs_super_ops.drop_inode was pointing to generic_delete_inode. Now this pointer is left set to NULL so that the default behaviour occurs instead. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/afs/super.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs') diff --git a/fs/afs/super.c b/fs/afs/super.c index 579af63..370cecc 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -47,7 +47,6 @@ struct file_system_type afs_fs_type = { static const struct super_operations afs_super_ops = { .statfs = afs_statfs, .alloc_inode = afs_alloc_inode, - .drop_inode = generic_delete_inode, .write_inode = afs_write_inode, .destroy_inode = afs_destroy_inode, .clear_inode = afs_clear_inode, -- cgit v1.1 From bb33ed6345d6156484f39089aa8b52f44ce76609 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 15 May 2007 23:57:04 -0700 Subject: AFS: Fix afs_prepare_write() afs_prepare_write() should not mark a page up to date if it only partially fills it in, in expectation of the caller filling in the rest prior to calling commit_write(). commit_write(), however, should mark the page up to date. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/afs/write.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/afs/write.c b/fs/afs/write.c index 28f3751..a03b92a 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -206,7 +206,6 @@ int afs_prepare_write(struct file *file, struct page *page, _leave(" = %d [prep]", ret); return ret; } - SetPageUptodate(page); } try_again: @@ -311,8 +310,8 @@ int afs_commit_write(struct file *file, struct page *page, spin_unlock(&vnode->writeback_lock); } + SetPageUptodate(page); set_page_dirty(page); - if (PageDirty(page)) _debug("dirtied"); -- cgit v1.1 From a35afb830f8d71ec211531aeb9a621b09a2efb39 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 16 May 2007 22:10:57 -0700 Subject: Remove SLAB_CTOR_CONSTRUCTOR SLAB_CTOR_CONSTRUCTOR is always specified. No point in checking it. Signed-off-by: Christoph Lameter Cc: David Howells Cc: Jens Axboe Cc: Steven French Cc: Michael Halcrow Cc: OGAWA Hirofumi Cc: Miklos Szeredi Cc: Steven Whitehouse Cc: Roman Zippel Cc: David Woodhouse Cc: Dave Kleikamp Cc: Trond Myklebust Cc: "J. Bruce Fields" Cc: Anton Altaparmakov Cc: Mark Fasheh Cc: Paul Mackerras Cc: Christoph Hellwig Cc: Jan Kara Cc: David Chinner Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/adfs/super.c | 3 +-- fs/affs/super.c | 8 +++----- fs/afs/super.c | 20 +++++++++----------- fs/befs/linuxvfs.c | 6 ++---- fs/bfs/inode.c | 3 +-- fs/block_dev.c | 16 +++++++--------- fs/buffer.c | 22 ++++------------------ fs/cifs/cifsfs.c | 6 ++---- fs/coda/inode.c | 3 +-- fs/ecryptfs/main.c | 3 +-- fs/efs/super.c | 3 +-- fs/ext2/super.c | 8 +++----- fs/ext3/super.c | 10 ++++------ fs/ext4/super.c | 10 ++++------ fs/fat/cache.c | 3 +-- fs/fat/inode.c | 14 ++++++-------- fs/fuse/inode.c | 3 +-- fs/gfs2/main.c | 34 ++++++++++++++++------------------ fs/hfs/super.c | 3 +-- fs/hfsplus/super.c | 3 +-- fs/hpfs/super.c | 8 +++----- fs/hugetlbfs/inode.c | 3 +-- fs/inode.c | 3 +-- fs/isofs/inode.c | 3 +-- fs/jffs2/super.c | 6 ++---- fs/jfs/jfs_metapage.c | 18 ++++++++---------- fs/jfs/super.c | 22 ++++++++++------------ fs/locks.c | 3 --- fs/minix/inode.c | 3 +-- fs/ncpfs/inode.c | 6 ++---- fs/nfs/inode.c | 28 +++++++++++++--------------- fs/ntfs/super.c | 3 +-- fs/ocfs2/dlm/dlmfs.c | 8 +++----- fs/ocfs2/super.c | 38 ++++++++++++++++++-------------------- fs/openpromfs/inode.c | 3 +-- fs/proc/inode.c | 3 +-- fs/qnx4/inode.c | 3 +-- fs/reiserfs/super.c | 10 ++++------ fs/romfs/inode.c | 7 +++---- fs/smbfs/inode.c | 3 +-- fs/sysv/inode.c | 3 +-- fs/udf/super.c | 6 ++---- fs/ufs/super.c | 3 +-- fs/xfs/linux-2.6/xfs_super.c | 3 +-- 44 files changed, 149 insertions(+), 228 deletions(-) (limited to 'fs') diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 30c2965..de2ed5c 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -232,8 +232,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/affs/super.c b/fs/affs/super.c index beff7d2..b800d45 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -87,11 +87,9 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct affs_inode_info *ei = (struct affs_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - init_MUTEX(&ei->i_link_lock); - init_MUTEX(&ei->i_ext_lock); - inode_init_once(&ei->vfs_inode); - } + init_MUTEX(&ei->i_link_lock); + init_MUTEX(&ei->i_ext_lock); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/afs/super.c b/fs/afs/super.c index 370cecc..8d47ad8 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -451,17 +451,15 @@ static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep, { struct afs_vnode *vnode = _vnode; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - memset(vnode, 0, sizeof(*vnode)); - inode_init_once(&vnode->vfs_inode); - init_waitqueue_head(&vnode->update_waitq); - mutex_init(&vnode->permits_lock); - mutex_init(&vnode->validate_lock); - spin_lock_init(&vnode->writeback_lock); - spin_lock_init(&vnode->lock); - INIT_LIST_HEAD(&vnode->writebacks); - INIT_WORK(&vnode->cb_broken_work, afs_broken_callback_work); - } + memset(vnode, 0, sizeof(*vnode)); + inode_init_once(&vnode->vfs_inode); + init_waitqueue_head(&vnode->update_waitq); + mutex_init(&vnode->permits_lock); + mutex_init(&vnode->validate_lock); + spin_lock_init(&vnode->writeback_lock); + spin_lock_init(&vnode->lock); + INIT_LIST_HEAD(&vnode->writebacks); + INIT_WORK(&vnode->cb_broken_work, afs_broken_callback_work); } /* diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index fe96108..a5c5171 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -292,10 +292,8 @@ befs_destroy_inode(struct inode *inode) static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) { struct befs_inode_info *bi = (struct befs_inode_info *) foo; - - if (flags & SLAB_CTOR_CONSTRUCTOR) { - inode_init_once(&bi->vfs_inode); - } + + inode_init_once(&bi->vfs_inode); } static void diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index edc08d8..58c7bd9 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -248,8 +248,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct bfs_inode_info *bi = foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&bi->vfs_inode); + inode_init_once(&bi->vfs_inode); } static int init_inodecache(void) diff --git a/fs/block_dev.c b/fs/block_dev.c index 7428992..ea1480a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -458,17 +458,15 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag struct bdev_inode *ei = (struct bdev_inode *) foo; struct block_device *bdev = &ei->bdev; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - memset(bdev, 0, sizeof(*bdev)); - mutex_init(&bdev->bd_mutex); - sema_init(&bdev->bd_mount_sem, 1); - INIT_LIST_HEAD(&bdev->bd_inodes); - INIT_LIST_HEAD(&bdev->bd_list); + memset(bdev, 0, sizeof(*bdev)); + mutex_init(&bdev->bd_mutex); + sema_init(&bdev->bd_mount_sem, 1); + INIT_LIST_HEAD(&bdev->bd_inodes); + INIT_LIST_HEAD(&bdev->bd_list); #ifdef CONFIG_SYSFS - INIT_LIST_HEAD(&bdev->bd_holder_list); + INIT_LIST_HEAD(&bdev->bd_holder_list); #endif - inode_init_once(&ei->vfs_inode); - } + inode_init_once(&ei->vfs_inode); } static inline void __bd_forget(struct inode *inode) diff --git a/fs/buffer.c b/fs/buffer.c index aecd057..3deeb88 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2898,8 +2898,9 @@ static void recalc_bh_state(void) struct buffer_head *alloc_buffer_head(gfp_t gfp_flags) { - struct buffer_head *ret = kmem_cache_alloc(bh_cachep, gfp_flags); + struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags); if (ret) { + INIT_LIST_HEAD(&ret->b_assoc_buffers); get_cpu_var(bh_accounting).nr++; recalc_bh_state(); put_cpu_var(bh_accounting); @@ -2918,17 +2919,6 @@ void free_buffer_head(struct buffer_head *bh) } EXPORT_SYMBOL(free_buffer_head); -static void -init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags) -{ - if (flags & SLAB_CTOR_CONSTRUCTOR) { - struct buffer_head * bh = (struct buffer_head *)data; - - memset(bh, 0, sizeof(*bh)); - INIT_LIST_HEAD(&bh->b_assoc_buffers); - } -} - static void buffer_exit_cpu(int cpu) { int i; @@ -2955,12 +2945,8 @@ void __init buffer_init(void) { int nrpages; - bh_cachep = kmem_cache_create("buffer_head", - sizeof(struct buffer_head), 0, - (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC| - SLAB_MEM_SPREAD), - init_buffer_head, - NULL); + bh_cachep = KMEM_CACHE(buffer_head, + SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD); /* * Limit the bh occupancy to 10% of ZONE_NORMAL diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 8568e10..d38c69b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -701,10 +701,8 @@ cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags) { struct cifsInodeInfo *cifsi = inode; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - inode_init_once(&cifsi->vfs_inode); - INIT_LIST_HEAD(&cifsi->lockList); - } + inode_init_once(&cifsi->vfs_inode); + INIT_LIST_HEAD(&cifsi->lockList); } static int diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 0aaff36..dbff1bd 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -62,8 +62,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct coda_inode_info *ei = (struct coda_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } int coda_init_inodecache(void) diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 8cbf3f6..606128f 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -583,8 +583,7 @@ inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags) { struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } static struct ecryptfs_cache_info { diff --git a/fs/efs/super.c b/fs/efs/super.c index ba7a8b9..e0a6839 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -72,8 +72,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct efs_inode_info *ei = (struct efs_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 685a1c2..16337bf 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -160,13 +160,11 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - rwlock_init(&ei->i_meta_lock); + rwlock_init(&ei->i_meta_lock); #ifdef CONFIG_EXT2_FS_XATTR - init_rwsem(&ei->xattr_sem); + init_rwsem(&ei->xattr_sem); #endif - inode_init_once(&ei->vfs_inode); - } + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 54d3c90..6e30629 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -466,14 +466,12 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - INIT_LIST_HEAD(&ei->i_orphan); + INIT_LIST_HEAD(&ei->i_orphan); #ifdef CONFIG_EXT3_FS_XATTR - init_rwsem(&ei->xattr_sem); + init_rwsem(&ei->xattr_sem); #endif - mutex_init(&ei->truncate_mutex); - inode_init_once(&ei->vfs_inode); - } + mutex_init(&ei->truncate_mutex); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7191269..cb9afdd 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -517,14 +517,12 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - INIT_LIST_HEAD(&ei->i_orphan); + INIT_LIST_HEAD(&ei->i_orphan); #ifdef CONFIG_EXT4DEV_FS_XATTR - init_rwsem(&ei->xattr_sem); + init_rwsem(&ei->xattr_sem); #endif - mutex_init(&ei->truncate_mutex); - inode_init_once(&ei->vfs_inode); - } + mutex_init(&ei->truncate_mutex); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 1959143..3c9c8a1 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c @@ -40,8 +40,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct fat_cache *cache = (struct fat_cache *)foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - INIT_LIST_HEAD(&cache->cache_list); + INIT_LIST_HEAD(&cache->cache_list); } int __init fat_cache_init(void) diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 2c55e8d..479722d 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -500,14 +500,12 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - spin_lock_init(&ei->cache_lru_lock); - ei->nr_caches = 0; - ei->cache_valid_id = FAT_CACHE_VALID + 1; - INIT_LIST_HEAD(&ei->cache_lru); - INIT_HLIST_NODE(&ei->i_fat_hash); - inode_init_once(&ei->vfs_inode); - } + spin_lock_init(&ei->cache_lru_lock); + ei->nr_caches = 0; + ei->cache_valid_id = FAT_CACHE_VALID + 1; + INIT_LIST_HEAD(&ei->cache_lru); + INIT_HLIST_NODE(&ei->i_fat_hash); + inode_init_once(&ei->vfs_inode); } static int __init fat_init_inodecache(void) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 1397018..c3a2ad0 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -687,8 +687,7 @@ static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep, { struct inode * inode = foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(inode); + inode_init_once(inode); } static int __init fuse_fs_init(void) diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index e460487..787a0ed 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c @@ -27,29 +27,27 @@ static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct gfs2_inode *ip = foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - inode_init_once(&ip->i_inode); - spin_lock_init(&ip->i_spin); - init_rwsem(&ip->i_rw_mutex); - memset(ip->i_cache, 0, sizeof(ip->i_cache)); - } + + inode_init_once(&ip->i_inode); + spin_lock_init(&ip->i_spin); + init_rwsem(&ip->i_rw_mutex); + memset(ip->i_cache, 0, sizeof(ip->i_cache)); } static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct gfs2_glock *gl = foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - INIT_HLIST_NODE(&gl->gl_list); - spin_lock_init(&gl->gl_spin); - INIT_LIST_HEAD(&gl->gl_holders); - INIT_LIST_HEAD(&gl->gl_waiters1); - INIT_LIST_HEAD(&gl->gl_waiters3); - gl->gl_lvb = NULL; - atomic_set(&gl->gl_lvb_count, 0); - INIT_LIST_HEAD(&gl->gl_reclaim); - INIT_LIST_HEAD(&gl->gl_ail_list); - atomic_set(&gl->gl_ail_count, 0); - } + + INIT_HLIST_NODE(&gl->gl_list); + spin_lock_init(&gl->gl_spin); + INIT_LIST_HEAD(&gl->gl_holders); + INIT_LIST_HEAD(&gl->gl_waiters1); + INIT_LIST_HEAD(&gl->gl_waiters3); + gl->gl_lvb = NULL; + atomic_set(&gl->gl_lvb_count, 0); + INIT_LIST_HEAD(&gl->gl_reclaim); + INIT_LIST_HEAD(&gl->gl_ail_list); + atomic_set(&gl->gl_ail_count, 0); } /** diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 4f1888f..92cf875 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -434,8 +434,7 @@ static void hfs_init_once(void *p, struct kmem_cache *cachep, unsigned long flag { struct hfs_inode_info *i = p; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&i->vfs_inode); + inode_init_once(&i->vfs_inode); } static int __init init_hfs_fs(void) diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 37afbec..ebd1b38 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -470,8 +470,7 @@ static void hfsplus_init_once(void *p, struct kmem_cache *cachep, unsigned long { struct hfsplus_inode_info *i = p; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&i->vfs_inode); + inode_init_once(&i->vfs_inode); } static int __init init_hfsplus_fs(void) diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 1b95f39f..fca1165d 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -176,11 +176,9 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - mutex_init(&ei->i_mutex); - mutex_init(&ei->i_parent_mutex); - inode_init_once(&ei->vfs_inode); - } + mutex_init(&ei->i_mutex); + mutex_init(&ei->i_parent_mutex); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 98959b8..aa083dd 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -556,8 +556,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } const struct file_operations hugetlbfs_file_operations = { diff --git a/fs/inode.c b/fs/inode.c index df2ef15..9a012cc 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -213,8 +213,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct inode * inode = (struct inode *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(inode); + inode_init_once(inode); } /* diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index e99f7ff..5c3eecf 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -77,8 +77,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags { struct iso_inode_info *ei = foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 45368f8..6488af4 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -47,10 +47,8 @@ static void jffs2_i_init_once(void * foo, struct kmem_cache * cachep, unsigned l { struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - init_MUTEX(&ei->sem); - inode_init_once(&ei->vfs_inode); - } + init_MUTEX(&ei->sem); + inode_init_once(&ei->vfs_inode); } static int jffs2_sync_fs(struct super_block *sb, int wait) diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 6b3acb0..43d4f69 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -184,16 +184,14 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { struct metapage *mp = (struct metapage *)foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - mp->lid = 0; - mp->lsn = 0; - mp->flag = 0; - mp->data = NULL; - mp->clsn = 0; - mp->log = NULL; - set_bit(META_free, &mp->flag); - init_waitqueue_head(&mp->wait); - } + mp->lid = 0; + mp->lsn = 0; + mp->flag = 0; + mp->data = NULL; + mp->clsn = 0; + mp->log = NULL; + set_bit(META_free, &mp->flag); + init_waitqueue_head(&mp->wait); } static inline struct metapage *alloc_metapage(gfp_t gfp_mask) diff --git a/fs/jfs/super.c b/fs/jfs/super.c index ea9dc3e..20e4ac1 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -752,20 +752,18 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags { struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - memset(jfs_ip, 0, sizeof(struct jfs_inode_info)); - INIT_LIST_HEAD(&jfs_ip->anon_inode_list); - init_rwsem(&jfs_ip->rdwrlock); - mutex_init(&jfs_ip->commit_mutex); - init_rwsem(&jfs_ip->xattr_sem); - spin_lock_init(&jfs_ip->ag_lock); - jfs_ip->active_ag = -1; + memset(jfs_ip, 0, sizeof(struct jfs_inode_info)); + INIT_LIST_HEAD(&jfs_ip->anon_inode_list); + init_rwsem(&jfs_ip->rdwrlock); + mutex_init(&jfs_ip->commit_mutex); + init_rwsem(&jfs_ip->xattr_sem); + spin_lock_init(&jfs_ip->ag_lock); + jfs_ip->active_ag = -1; #ifdef CONFIG_JFS_POSIX_ACL - jfs_ip->i_acl = JFS_ACL_NOT_CACHED; - jfs_ip->i_default_acl = JFS_ACL_NOT_CACHED; + jfs_ip->i_acl = JFS_ACL_NOT_CACHED; + jfs_ip->i_default_acl = JFS_ACL_NOT_CACHED; #endif - inode_init_once(&jfs_ip->vfs_inode); - } + inode_init_once(&jfs_ip->vfs_inode); } static int __init init_jfs_fs(void) diff --git a/fs/locks.c b/fs/locks.c index 8ec16ab..431a8b8 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -203,9 +203,6 @@ static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags) { struct file_lock *lock = (struct file_lock *) foo; - if (!(flags & SLAB_CTOR_CONSTRUCTOR)) - return; - locks_init_lock(lock); } diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 2f4d43a..be40446 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -73,8 +73,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct minix_inode_info *ei = (struct minix_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index c29f00a..cf06eb9 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -60,10 +60,8 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - mutex_init(&ei->open_mutex); - inode_init_once(&ei->vfs_inode); - } + mutex_init(&ei->open_mutex); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2a3fd95..2b26ad7 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1164,21 +1164,19 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct nfs_inode *nfsi = (struct nfs_inode *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - inode_init_once(&nfsi->vfs_inode); - spin_lock_init(&nfsi->req_lock); - INIT_LIST_HEAD(&nfsi->dirty); - INIT_LIST_HEAD(&nfsi->commit); - INIT_LIST_HEAD(&nfsi->open_files); - INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); - INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); - INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); - atomic_set(&nfsi->data_updates, 0); - nfsi->ndirty = 0; - nfsi->ncommit = 0; - nfsi->npages = 0; - nfs4_init_once(nfsi); - } + inode_init_once(&nfsi->vfs_inode); + spin_lock_init(&nfsi->req_lock); + INIT_LIST_HEAD(&nfsi->dirty); + INIT_LIST_HEAD(&nfsi->commit); + INIT_LIST_HEAD(&nfsi->open_files); + INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); + INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); + INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); + atomic_set(&nfsi->data_updates, 0); + nfsi->ndirty = 0; + nfsi->ncommit = 0; + nfsi->npages = 0; + nfs4_init_once(nfsi); } static int __init nfs_init_inodecache(void) diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 21d834e..4566b91 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -3085,8 +3085,7 @@ static void ntfs_big_inode_init_once(void *foo, struct kmem_cache *cachep, { ntfs_inode *ni = (ntfs_inode *)foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(VFS_I(ni)); + inode_init_once(VFS_I(ni)); } /* diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index 5671cf9..fd8cb1b 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c @@ -262,12 +262,10 @@ static void dlmfs_init_once(void *foo, struct dlmfs_inode_private *ip = (struct dlmfs_inode_private *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - ip->ip_dlm = NULL; - ip->ip_parent = NULL; + ip->ip_dlm = NULL; + ip->ip_parent = NULL; - inode_init_once(&ip->ip_vfs_inode); - } + inode_init_once(&ip->ip_vfs_inode); } static struct inode *dlmfs_alloc_inode(struct super_block *sb) diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 7c5e3f5..86b559c 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -937,31 +937,29 @@ static void ocfs2_inode_init_once(void *data, { struct ocfs2_inode_info *oi = data; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - oi->ip_flags = 0; - oi->ip_open_count = 0; - spin_lock_init(&oi->ip_lock); - ocfs2_extent_map_init(&oi->vfs_inode); - INIT_LIST_HEAD(&oi->ip_io_markers); - oi->ip_created_trans = 0; - oi->ip_last_trans = 0; - oi->ip_dir_start_lookup = 0; + oi->ip_flags = 0; + oi->ip_open_count = 0; + spin_lock_init(&oi->ip_lock); + ocfs2_extent_map_init(&oi->vfs_inode); + INIT_LIST_HEAD(&oi->ip_io_markers); + oi->ip_created_trans = 0; + oi->ip_last_trans = 0; + oi->ip_dir_start_lookup = 0; - init_rwsem(&oi->ip_alloc_sem); - mutex_init(&oi->ip_io_mutex); + init_rwsem(&oi->ip_alloc_sem); + mutex_init(&oi->ip_io_mutex); - oi->ip_blkno = 0ULL; - oi->ip_clusters = 0; + oi->ip_blkno = 0ULL; + oi->ip_clusters = 0; - ocfs2_lock_res_init_once(&oi->ip_rw_lockres); - ocfs2_lock_res_init_once(&oi->ip_meta_lockres); - ocfs2_lock_res_init_once(&oi->ip_data_lockres); - ocfs2_lock_res_init_once(&oi->ip_open_lockres); + ocfs2_lock_res_init_once(&oi->ip_rw_lockres); + ocfs2_lock_res_init_once(&oi->ip_meta_lockres); + ocfs2_lock_res_init_once(&oi->ip_data_lockres); + ocfs2_lock_res_init_once(&oi->ip_open_lockres); - ocfs2_metadata_cache_init(&oi->vfs_inode); + ocfs2_metadata_cache_init(&oi->vfs_inode); - inode_init_once(&oi->vfs_inode); - } + inode_init_once(&oi->vfs_inode); } static int ocfs2_initialize_mem_caches(void) diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index 731a90e..e623973 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c @@ -419,8 +419,7 @@ static void op_inode_init_once(void *data, struct kmem_cache * cachep, unsigned { struct op_inode_info *oi = (struct op_inode_info *) data; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&oi->vfs_inode); + inode_init_once(&oi->vfs_inode); } static int __init init_openprom_fs(void) diff --git a/fs/proc/inode.c b/fs/proc/inode.c index b817190..d5ce65c 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -109,8 +109,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct proc_inode *ei = (struct proc_inode *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } int __init proc_init_inodecache(void) diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 75fc849..8d256eb 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -536,8 +536,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, { struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index c776214..b4ac911 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -511,14 +511,12 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags { struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - INIT_LIST_HEAD(&ei->i_prealloc_list); - inode_init_once(&ei->vfs_inode); + INIT_LIST_HEAD(&ei->i_prealloc_list); + inode_init_once(&ei->vfs_inode); #ifdef CONFIG_REISERFS_FS_POSIX_ACL - ei->i_acl_access = NULL; - ei->i_acl_default = NULL; + ei->i_acl_access = NULL; + ei->i_acl_default = NULL; #endif - } } static int init_inodecache(void) diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index 8042851..2284e03 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c @@ -566,12 +566,11 @@ static void romfs_destroy_inode(struct inode *inode) kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode)); } -static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) +static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) { - struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; + struct romfs_inode_info *ei = foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 424a3dd..5c9243a 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -70,8 +70,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct smb_inode_info *ei = (struct smb_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 3152d74..5644116 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -322,8 +322,7 @@ static void init_once(void *p, struct kmem_cache *cachep, unsigned long flags) { struct sysv_inode_info *si = (struct sysv_inode_info *)p; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&si->vfs_inode); + inode_init_once(&si->vfs_inode); } const struct super_operations sysv_sops = { diff --git a/fs/udf/super.c b/fs/udf/super.c index 9b8644a..3a743d8 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -134,10 +134,8 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct udf_inode_info *ei = (struct udf_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) { - ei->i_ext.i_data = NULL; - inode_init_once(&ei->vfs_inode); - } + ei->i_ext.i_data = NULL; + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/ufs/super.c b/fs/ufs/super.c index be7c48c..22ff6ed 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1237,8 +1237,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag { struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(&ei->vfs_inode); + inode_init_once(&ei->vfs_inode); } static int init_inodecache(void) diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 14e2cbe..bf9a9d5 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -360,8 +360,7 @@ xfs_fs_inode_init_once( kmem_zone_t *zonep, unsigned long flags) { - if (flags & SLAB_CTOR_CONSTRUCTOR) - inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); + inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); } STATIC int -- cgit v1.1 From 8317f14b60c02c69cf7f594e2aabc8a3fdc9618d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 16 May 2007 22:11:08 -0700 Subject: simplify compat_sys_timerfd Just thought this is easier to read. Acked-by: Davide Libenzi Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/compat.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'fs') diff --git a/fs/compat.c b/fs/compat.c index 7b21b0a..1de2331 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -2230,21 +2230,16 @@ asmlinkage long compat_sys_signalfd(int ufd, asmlinkage long compat_sys_timerfd(int ufd, int clockid, int flags, const struct compat_itimerspec __user *utmr) { - long res; struct itimerspec t; struct itimerspec __user *ut; - res = -EFAULT; if (get_compat_itimerspec(&t, utmr)) - goto err_exit; + return -EFAULT; ut = compat_alloc_user_space(sizeof(*ut)); - if (copy_to_user(ut, &t, sizeof(t)) ) - goto err_exit; + if (copy_to_user(ut, &t, sizeof(t))) + return -EFAULT; - res = sys_timerfd(ufd, clockid, flags, ut); -err_exit: - return res; + return sys_timerfd(ufd, clockid, flags, ut); } #endif /* CONFIG_TIMERFD */ - -- cgit v1.1 From 71ce92f3fa442069670a52fa6230a6064c4517b3 Mon Sep 17 00:00:00 2001 From: Dan Aloni Date: Wed, 16 May 2007 22:11:16 -0700 Subject: make sysctl/kernel/core_pattern and fs/exec.c agree on maximum core filename size Make sysctl/kernel/core_pattern and fs/exec.c agree on maximum core filename size and change it to 128, so that extensive patterns such as '/local/cores/%e-%h-%s-%t-%p.core' won't result in truncated filename generation. Signed-off-by: Dan Aloni Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/exec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/exec.c b/fs/exec.c index 70fa365..0b68588 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -60,7 +60,7 @@ #endif int core_uses_pid; -char core_pattern[128] = "core"; +char core_pattern[CORENAME_MAX_SIZE] = "core"; int suid_dumpable = 0; EXPORT_SYMBOL(suid_dumpable); @@ -1264,8 +1264,6 @@ int set_binfmt(struct linux_binfmt *new) EXPORT_SYMBOL(set_binfmt); -#define CORENAME_MAX_SIZE 64 - /* format_corename will inspect the pattern parameter, and output a * name into corename, which must have space for at least * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. -- cgit v1.1 From c9f2875b7968453a852e1de5d3504fd2241e8989 Mon Sep 17 00:00:00 2001 From: Nate Diller Date: Wed, 16 May 2007 22:11:17 -0700 Subject: ecryptfs: use zero_user_page Use zero_user_page() instead of open-coding it. Signed-off-by: Nate Diller Cc: Michael Halcrow Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ecryptfs/mmap.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'fs') diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 0770c4b..88ea669 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -364,18 +364,14 @@ static int fill_zeros_to_end_of_page(struct page *page, unsigned int to) { struct inode *inode = page->mapping->host; int end_byte_in_page; - char *page_virt; if ((i_size_read(inode) / PAGE_CACHE_SIZE) != page->index) goto out; end_byte_in_page = i_size_read(inode) % PAGE_CACHE_SIZE; if (to > end_byte_in_page) end_byte_in_page = to; - page_virt = kmap_atomic(page, KM_USER0); - memset((page_virt + end_byte_in_page), 0, - (PAGE_CACHE_SIZE - end_byte_in_page)); - kunmap_atomic(page_virt, KM_USER0); - flush_dcache_page(page); + zero_user_page(page, end_byte_in_page, + PAGE_CACHE_SIZE - end_byte_in_page, KM_USER0); out: return 0; } @@ -740,7 +736,6 @@ int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) { int rc = 0; struct page *tmp_page; - char *tmp_page_virt; tmp_page = ecryptfs_get1page(file, index); if (IS_ERR(tmp_page)) { @@ -757,10 +752,7 @@ int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) page_cache_release(tmp_page); goto out; } - tmp_page_virt = kmap_atomic(tmp_page, KM_USER0); - memset(((char *)tmp_page_virt + start), 0, num_zeros); - kunmap_atomic(tmp_page_virt, KM_USER0); - flush_dcache_page(tmp_page); + zero_user_page(tmp_page, start, num_zeros, KM_USER0); rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros); if (rc < 0) { ecryptfs_printk(KERN_ERR, "Error attempting to write zero's " -- cgit v1.1 From 7925409e202a41176b729671eab6e610a54153cd Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 16 May 2007 22:11:19 -0700 Subject: circular locking dependency found in QUOTA OFF i_mutex on quota files is special. Unlike i_mutexes for other inodes it is acquired under dqonoff_mutex. Tell lockdep about this lock ranking. Also comment and code in quota_sync_sb() seem to be bogus (as i_mutex for quota file can be acquired under dqonoff_mutex). Move truncate_inode_pages() call under dqonoff_mutex and save some problems with races... Signed-off-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/dquot.c | 2 +- fs/quota.c | 23 +++++++---------------- 2 files changed, 8 insertions(+), 17 deletions(-) (limited to 'fs') diff --git a/fs/dquot.c b/fs/dquot.c index 3a99584..8819d28 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -1421,7 +1421,7 @@ int vfs_quota_off(struct super_block *sb, int type) /* If quota was reenabled in the meantime, we have * nothing to do */ if (!sb_has_quota_enabled(sb, cnt)) { - mutex_lock(&toputinode[cnt]->i_mutex); + mutex_lock_nested(&toputinode[cnt]->i_mutex, I_MUTEX_QUOTA); toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | S_NOATIME | S_NOQUOTA); truncate_inode_pages(&toputinode[cnt]->i_data, 0); diff --git a/fs/quota.c b/fs/quota.c index e9d88fd0..9f237d6 100644 --- a/fs/quota.c +++ b/fs/quota.c @@ -157,7 +157,6 @@ static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t static void quota_sync_sb(struct super_block *sb, int type) { int cnt; - struct inode *discard[MAXQUOTAS]; sb->s_qcop->quota_sync(sb, type); /* This is not very clever (and fast) but currently I don't know about @@ -167,29 +166,21 @@ static void quota_sync_sb(struct super_block *sb, int type) sb->s_op->sync_fs(sb, 1); sync_blockdev(sb->s_bdev); - /* Now when everything is written we can discard the pagecache so - * that userspace sees the changes. We need i_mutex and so we could - * not do it inside dqonoff_mutex. Moreover we need to be carefull - * about races with quotaoff() (that is the reason why we have own - * reference to inode). */ + /* + * Now when everything is written we can discard the pagecache so + * that userspace sees the changes. + */ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - discard[cnt] = NULL; if (type != -1 && cnt != type) continue; if (!sb_has_quota_enabled(sb, cnt)) continue; - discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]); + mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex, I_MUTEX_QUOTA); + truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0); + mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex); } mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - if (discard[cnt]) { - mutex_lock(&discard[cnt]->i_mutex); - truncate_inode_pages(&discard[cnt]->i_data, 0); - mutex_unlock(&discard[cnt]->i_mutex); - iput(discard[cnt]); - } - } } void sync_dquots(struct super_block *sb, int type) -- cgit v1.1 From ea125892a17f43919c726777ed1e4929d41e7984 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 16 May 2007 22:11:21 -0700 Subject: Fix page allocation flags in grow_dev_page() grow_dev_page() simply passes GFP_NOFS to find_or_create_page. This means the allocation of radix tree nodes is done with GFP_NOFS and the allocation of a new page is done using GFP_NOFS. The mapping has a flags field that contains the necessary allocation flags for the page cache allocation. These need to be consulted in order to get DMA and HIGHMEM allocations etc right. And yes a blockdev could be allowing Highmem allocations if its a ramdisk. Cc: Hugh Dickins Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/buffer.c b/fs/buffer.c index 3deeb88..49590d59 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -981,7 +981,8 @@ grow_dev_page(struct block_device *bdev, sector_t block, struct page *page; struct buffer_head *bh; - page = find_or_create_page(inode->i_mapping, index, GFP_NOFS); + page = find_or_create_page(inode->i_mapping, index, + mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); if (!page) return NULL; -- cgit v1.1 From d48eb2331595224ffe89665e79721d44b40bb047 Mon Sep 17 00:00:00 2001 From: Davide Libenzi Date: Fri, 18 May 2007 12:02:33 -0700 Subject: eventfd use waitqueue lock ... The eventfd was using the unlocked waitqueue operations, but it was using a different lock, so poll_wait() would race with it. This makes eventfd directly use the waitqueue lock. Signed-off-by: Davide Libenzi Signed-off-by: Linus Torvalds --- fs/eventfd.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'fs') diff --git a/fs/eventfd.c b/fs/eventfd.c index 480e2b3..2ce19c0 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -17,7 +17,6 @@ #include struct eventfd_ctx { - spinlock_t lock; wait_queue_head_t wqh; /* * Every time that a write(2) is performed on an eventfd, the @@ -45,13 +44,13 @@ int eventfd_signal(struct file *file, int n) if (n < 0) return -EINVAL; - spin_lock_irqsave(&ctx->lock, flags); + spin_lock_irqsave(&ctx->wqh.lock, flags); if (ULLONG_MAX - ctx->count < n) n = (int) (ULLONG_MAX - ctx->count); ctx->count += n; if (waitqueue_active(&ctx->wqh)) wake_up_locked(&ctx->wqh); - spin_unlock_irqrestore(&ctx->lock, flags); + spin_unlock_irqrestore(&ctx->wqh.lock, flags); return n; } @@ -70,14 +69,14 @@ static unsigned int eventfd_poll(struct file *file, poll_table *wait) poll_wait(file, &ctx->wqh, wait); - spin_lock_irqsave(&ctx->lock, flags); + spin_lock_irqsave(&ctx->wqh.lock, flags); if (ctx->count > 0) events |= POLLIN; if (ctx->count == ULLONG_MAX) events |= POLLERR; if (ULLONG_MAX - 1 > ctx->count) events |= POLLOUT; - spin_unlock_irqrestore(&ctx->lock, flags); + spin_unlock_irqrestore(&ctx->wqh.lock, flags); return events; } @@ -92,7 +91,7 @@ static ssize_t eventfd_read(struct file *file, char __user *buf, size_t count, if (count < sizeof(ucnt)) return -EINVAL; - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); res = -EAGAIN; ucnt = ctx->count; if (ucnt > 0) @@ -110,9 +109,9 @@ static ssize_t eventfd_read(struct file *file, char __user *buf, size_t count, res = -ERESTARTSYS; break; } - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); schedule(); - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); } __remove_wait_queue(&ctx->wqh, &wait); __set_current_state(TASK_RUNNING); @@ -122,7 +121,7 @@ static ssize_t eventfd_read(struct file *file, char __user *buf, size_t count, if (waitqueue_active(&ctx->wqh)) wake_up_locked(&ctx->wqh); } - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); if (res > 0 && put_user(ucnt, (__u64 __user *) buf)) return -EFAULT; @@ -143,7 +142,7 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c return -EFAULT; if (ucnt == ULLONG_MAX) return -EINVAL; - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); res = -EAGAIN; if (ULLONG_MAX - ctx->count > ucnt) res = sizeof(ucnt); @@ -159,9 +158,9 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c res = -ERESTARTSYS; break; } - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); schedule(); - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); } __remove_wait_queue(&ctx->wqh, &wait); __set_current_state(TASK_RUNNING); @@ -171,7 +170,7 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c if (waitqueue_active(&ctx->wqh)) wake_up_locked(&ctx->wqh); } - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); return res; } @@ -210,7 +209,6 @@ asmlinkage long sys_eventfd(unsigned int count) return -ENOMEM; init_waitqueue_head(&ctx->wqh); - spin_lock_init(&ctx->lock); ctx->count = count; /* -- cgit v1.1 From 18963c01b8abf381f102752ce024c3582a716125 Mon Sep 17 00:00:00 2001 From: Davide Libenzi Date: Fri, 18 May 2007 12:02:33 -0700 Subject: timerfd use waitqueue lock ... The timerfd was using the unlocked waitqueue operations, but it was using a different lock, so poll_wait() would race with it. This makes timerfd directly use the waitqueue lock. Signed-off-by: Davide Libenzi Signed-off-by: Linus Torvalds --- fs/timerfd.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'fs') diff --git a/fs/timerfd.c b/fs/timerfd.c index e329e37..af9eca5 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -24,7 +24,6 @@ struct timerfd_ctx { struct hrtimer tmr; ktime_t tintv; - spinlock_t lock; wait_queue_head_t wqh; int expired; }; @@ -39,10 +38,10 @@ static enum hrtimer_restart timerfd_tmrproc(struct hrtimer *htmr) struct timerfd_ctx *ctx = container_of(htmr, struct timerfd_ctx, tmr); unsigned long flags; - spin_lock_irqsave(&ctx->lock, flags); + spin_lock_irqsave(&ctx->wqh.lock, flags); ctx->expired = 1; wake_up_locked(&ctx->wqh); - spin_unlock_irqrestore(&ctx->lock, flags); + spin_unlock_irqrestore(&ctx->wqh.lock, flags); return HRTIMER_NORESTART; } @@ -83,10 +82,10 @@ static unsigned int timerfd_poll(struct file *file, poll_table *wait) poll_wait(file, &ctx->wqh, wait); - spin_lock_irqsave(&ctx->lock, flags); + spin_lock_irqsave(&ctx->wqh.lock, flags); if (ctx->expired) events |= POLLIN; - spin_unlock_irqrestore(&ctx->lock, flags); + spin_unlock_irqrestore(&ctx->wqh.lock, flags); return events; } @@ -101,7 +100,7 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count, if (count < sizeof(ticks)) return -EINVAL; - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); res = -EAGAIN; if (!ctx->expired && !(file->f_flags & O_NONBLOCK)) { __add_wait_queue(&ctx->wqh, &wait); @@ -115,9 +114,9 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count, res = -ERESTARTSYS; break; } - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); schedule(); - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); } __remove_wait_queue(&ctx->wqh, &wait); __set_current_state(TASK_RUNNING); @@ -139,7 +138,7 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count, } else ticks = 1; } - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); if (ticks) res = put_user(ticks, buf) ? -EFAULT: sizeof(ticks); return res; @@ -176,7 +175,6 @@ asmlinkage long sys_timerfd(int ufd, int clockid, int flags, return -ENOMEM; init_waitqueue_head(&ctx->wqh); - spin_lock_init(&ctx->lock); timerfd_setup(ctx, clockid, flags, &ktmr); @@ -202,10 +200,10 @@ asmlinkage long sys_timerfd(int ufd, int clockid, int flags, * it to the new values. */ for (;;) { - spin_lock_irq(&ctx->lock); + spin_lock_irq(&ctx->wqh.lock); if (hrtimer_try_to_cancel(&ctx->tmr) >= 0) break; - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); cpu_relax(); } /* @@ -213,7 +211,7 @@ asmlinkage long sys_timerfd(int ufd, int clockid, int flags, */ timerfd_setup(ctx, clockid, flags, &ktmr); - spin_unlock_irq(&ctx->lock); + spin_unlock_irq(&ctx->wqh.lock); fput(file); } -- cgit v1.1 From 1d4be747a8077d90e10e1e0b0f8994abb4adacb4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 14 May 2007 16:58:35 +0900 Subject: fs: Kill sh dependency for binfmt_flat. Not really sure where this bogosity came from, but there's certainly nothing special about sh that lets us use flat files with the MMU on. Kill the dependency, and leave it as !MMU, like it is for all of the other nommu-wielding ports. Signed-off-by: Paul Mundt --- fs/Kconfig.binfmt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 74c6440..d4fc609 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt @@ -38,7 +38,7 @@ config BINFMT_ELF_FDPIC config BINFMT_FLAT tristate "Kernel support for flat binaries" - depends on !MMU || SUPERH + depends on !MMU help Support uClinux FLAT format binaries. -- cgit v1.1 From ff1be9ad61e3e17ba83702d8ed0b534e5b8ee15c Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Sun, 20 May 2007 23:39:40 +0900 Subject: Fix "fs: convert core functions to zero_user_page" The bug was introduced by 01f2705daf5a36208e69d7cf95db9c330f843af6. It misses to convert the first argument, it should be "new_page". This became a cause of fatfs corruption. Cc: Nate Diller Signed-off-by: OGAWA Hirofumi Signed-off-by: Linus Torvalds --- fs/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/buffer.c b/fs/buffer.c index 49590d59..aa68206 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2101,7 +2101,7 @@ int cont_prepare_write(struct page *page, unsigned offset, PAGE_CACHE_SIZE, get_block); if (status) goto out_unmap; - zero_user_page(page, zerofrom, PAGE_CACHE_SIZE - zerofrom, + zero_user_page(new_page, zerofrom, PAGE_CACHE_SIZE - zerofrom, KM_USER0); generic_commit_write(NULL, new_page, zerofrom, PAGE_CACHE_SIZE); unlock_page(new_page); -- cgit v1.1 From e8edc6e03a5c8562dc70a6d969f732bdb355a7e7 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 21 May 2007 01:22:52 +0400 Subject: Detach sched.h from mm.h First thing mm.h does is including sched.h solely for can_do_mlock() inline function which has "current" dereference inside. By dealing with can_do_mlock() mm.h can be detached from sched.h which is good. See below, why. This patch a) removes unconditional inclusion of sched.h from mm.h b) makes can_do_mlock() normal function in mm/mlock.c c) exports can_do_mlock() to not break compilation d) adds sched.h inclusions back to files that were getting it indirectly. e) adds less bloated headers to some files (asm/signal.h, jiffies.h) that were getting them indirectly Net result is: a) mm.h users would get less code to open, read, preprocess, parse, ... if they don't need sched.h b) sched.h stops being dependency for significant number of files: on x86_64 allmodconfig touching sched.h results in recompile of 4083 files, after patch it's only 3744 (-8.3%). Cross-compile tested on all arm defconfigs, all mips defconfigs, all powerpc defconfigs, alpha alpha-up arm i386 i386-up i386-defconfig i386-allnoconfig ia64 ia64-up m68k mips parisc parisc-up powerpc powerpc-up s390 s390-up sparc sparc-up sparc64 sparc64-up um-x86_64 x86_64 x86_64-up x86_64-defconfig x86_64-allnoconfig as well as my two usual configs. Signed-off-by: Alexey Dobriyan Signed-off-by: Linus Torvalds --- fs/9p/vfs_addr.c | 1 + fs/9p/vfs_dentry.c | 1 + fs/9p/vfs_inode.c | 1 + fs/9p/vfs_super.c | 1 + fs/affs/inode.c | 2 +- fs/affs/super.c | 1 + fs/afs/callback.c | 1 + fs/afs/cell.c | 1 + fs/afs/dir.c | 1 + fs/afs/inode.c | 1 + fs/afs/internal.h | 1 + fs/afs/main.c | 1 + fs/afs/proc.c | 1 + fs/afs/security.c | 1 + fs/afs/super.c | 1 + fs/afs/vlocation.c | 1 + fs/afs/vnode.c | 1 + fs/afs/volume.c | 1 + fs/binfmt_misc.c | 2 +- fs/coda/cache.c | 1 + fs/coda/upcall.c | 2 +- fs/configfs/inode.c | 1 + fs/ecryptfs/messaging.c | 2 +- fs/fifo.c | 1 + fs/fuse/file.c | 1 + fs/fuse/inode.c | 1 + fs/gfs2/glock.h | 1 + fs/hfs/inode.c | 1 + fs/hfsplus/inode.c | 1 + fs/hpfs/buffer.c | 2 +- fs/hpfs/namei.c | 2 +- fs/hpfs/super.c | 1 + fs/minix/bitmap.c | 1 + fs/ncpfs/file.c | 1 + fs/ncpfs/ioctl.c | 1 + fs/nfs/client.c | 2 +- fs/nfs/dir.c | 1 + fs/nfs/file.c | 1 + fs/nfs/inode.c | 2 +- fs/nfs/pagelist.c | 1 + fs/nfsd/nfs4callback.c | 1 + fs/nfsd/nfs4recover.c | 2 +- fs/nfsd/nfssvc.c | 2 +- fs/ntfs/file.c | 1 + fs/ramfs/inode.c | 2 +- fs/smbfs/dir.c | 1 + fs/smbfs/file.c | 1 + fs/smbfs/inode.c | 1 + fs/smbfs/request.c | 1 + fs/sysfs/inode.c | 1 + fs/udf/file.c | 1 + fs/udf/namei.c | 1 + 52 files changed, 52 insertions(+), 11 deletions(-) (limited to 'fs') diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 3128aa9..9ac4ffe9 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "debug.h" #include "v9fs.h" diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index 775e26e..d939604 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "debug.h" #include "v9fs.h" diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 7624821..c76cd8f 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "debug.h" #include "v9fs.h" diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 8eb9263..7bdf8b3 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "debug.h" #include "v9fs.h" diff --git a/fs/affs/inode.c b/fs/affs/inode.c index c5b9d73c..4609a6c 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -9,7 +9,7 @@ * * (C) 1991 Linus Torvalds - minix filesystem */ - +#include #include "affs.h" extern const struct inode_operations affs_symlink_inode_operations; diff --git a/fs/affs/super.c b/fs/affs/super.c index b800d45..6d0ebc3 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "affs.h" extern struct timezone sys_tz; diff --git a/fs/afs/callback.c b/fs/afs/callback.c index f64e40f..bacf518 100644 --- a/fs/afs/callback.c +++ b/fs/afs/callback.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "internal.h" unsigned afs_vnode_update_timeout = 10; diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 9b1311a..175a567 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "internal.h" diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 719af4f..546c595 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "internal.h" static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 47f5fed..d196840 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "internal.h" struct afs_iget_data { diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 4953ba5..2dac3ad 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "afs.h" #include "afs_vl.h" diff --git a/fs/afs/main.c b/fs/afs/main.c index f1f71ff..cd21195 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "internal.h" MODULE_DESCRIPTION("AFS Client File System"); diff --git a/fs/afs/proc.c b/fs/afs/proc.c index d5601f6..13df512 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "internal.h" diff --git a/fs/afs/security.c b/fs/afs/security.c index e0ea88b..566fe71 100644 --- a/fs/afs/security.c +++ b/fs/afs/security.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "internal.h" diff --git a/fs/afs/super.c b/fs/afs/super.c index 8d47ad8..2e8496b 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "internal.h" #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index 3370cdb..09e3ad0 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "internal.h" unsigned afs_vlocation_timeout = 10; /* volume location timeout in seconds */ diff --git a/fs/afs/vnode.c b/fs/afs/vnode.c index c36c98c..232c55d 100644 --- a/fs/afs/vnode.c +++ b/fs/afs/vnode.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "internal.h" #if 0 diff --git a/fs/afs/volume.c b/fs/afs/volume.c index dd160ca..8bab0e3 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "internal.h" static const char *afs_voltypes[] = { "R/W", "R/O", "BAK" }; diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 72d0b41..330fd3f 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -18,7 +18,7 @@ #include #include - +#include #include #include #include diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 5d05271..fcb88fa 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index a5b5e63..5faacdb 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -16,7 +16,7 @@ #include #include - +#include #include #include #include diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index 2ec9bea..ddc003a 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "configfs_internal.h" diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index 3baf253..a9d87c4 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ - +#include #include "ecryptfs_kernel.h" static LIST_HEAD(ecryptfs_msg_ctx_free_list); diff --git a/fs/fifo.c b/fs/fifo.c index 6e7df72..9785e36 100644 --- a/fs/fifo.c +++ b/fs/fifo.c @@ -12,6 +12,7 @@ #include #include #include +#include #include static void wait_for_partner(struct inode* inode, unsigned int *cnt) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index acfad65..d0ed60b 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -11,6 +11,7 @@ #include #include #include +#include static const struct file_operations fuse_direct_io_file_operations; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index c3a2ad0..78f7a1d 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -17,6 +17,7 @@ #include #include #include +#include MODULE_AUTHOR("Miklos Szeredi "); MODULE_DESCRIPTION("Filesystem in Userspace"); diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 11477ca..b3e152d 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h @@ -10,6 +10,7 @@ #ifndef __GLOCK_DOT_H__ #define __GLOCK_DOT_H__ +#include #include "incore.h" /* Flags for lock requests; used in gfs2_holder gh_flag field. diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index fafcba5..9a934db 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -13,6 +13,7 @@ #include #include +#include #include "hfs_fs.h" #include "btree.h" diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 642012a..45dab5d 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "hfsplus_fs.h" #include "hfsplus_raw.h" diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c index b52b738..b6fca54 100644 --- a/fs/hpfs/buffer.c +++ b/fs/hpfs/buffer.c @@ -5,7 +5,7 @@ * * general buffer i/o */ - +#include #include "hpfs_fn.h" void hpfs_lock_creation(struct super_block *s) diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 9953cf9..d256559 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -5,7 +5,7 @@ * * adding & removing files & directories */ - +#include #include "hpfs_fn.h" static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index fca1165d..29cc34a 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -12,6 +12,7 @@ #include #include #include +#include /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */ diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index c4a554d..99a12f1 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -15,6 +15,7 @@ #include #include #include +#include static int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 }; diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index addfd31..d3152f8 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "ncplib_kernel.h" diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 8843a83..c67b4bd 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -17,6 +17,7 @@ #include #include #include +#include #include diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 50c6821..881fa49 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -12,7 +12,7 @@ #include #include - +#include #include #include #include diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ac92e45..c27258b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "nfs4_fs.h" #include "delegation.h" diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 5eaee6d..9eb8eb4 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2b26ad7..bd9f5a8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -15,7 +15,7 @@ #include #include - +#include #include #include #include diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index e12054c..cbdd1c6 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 32ffea0..864090e 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index c7774e3..ebd03cc 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -45,7 +45,7 @@ #include #include #include - +#include #define NFSDDBG_FACILITY NFSDDBG_PROC diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index d7759ce..ff55950 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -9,7 +9,7 @@ */ #include - +#include #include #include #include diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 39a1669..7ed5639 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 4ace5d7..d40d22b 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -32,7 +32,7 @@ #include #include #include - +#include #include #include "internal.h" diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 50136b1..48da4fa 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index f161797..aea3f8a 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 5c9243a..6724a6c 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c index c288fbe..3f54a0f 100644 --- a/fs/smbfs/request.c +++ b/fs/smbfs/request.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 4de5c6b..bdd30e7 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "sysfs.h" diff --git a/fs/udf/file.c b/fs/udf/file.c index 40d5047d..51b5764 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "udf_i.h" #include "udf_sb.h" diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 91df492..51fe307 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -30,6 +30,7 @@ #include #include #include +#include static inline int udf_match(int len1, const char *name1, int len2, const char *name2) { -- cgit v1.1 From dde33348e53ecab687a9768bf5262f0b8f79b7f2 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Mon, 21 May 2007 09:37:42 +0100 Subject: LDM: Fix for Windows Vista dynamic disks This fixes the LDM driver so that it works with Windows Vista dynamic disks which are subtly different to Windows 2000/XP ones. The patch was needed to get a Vista formatted dynamic disk to be recognized and parsed successfully. Thanks go to Chris Teachworth for the report and testing. Cc: Richard Russon Signed-off-by: Anton Altaparmakov Signed-off-by: Linus Torvalds --- fs/partitions/Kconfig | 12 ++- fs/partitions/ldm.c | 206 ++++++++++++++++++++++++++++---------------------- fs/partitions/ldm.h | 6 +- 3 files changed, 127 insertions(+), 97 deletions(-) (limited to 'fs') diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index 7638a1c..a99acd8 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig @@ -166,8 +166,12 @@ config LDM_PARTITION depends on PARTITION_ADVANCED ---help--- Say Y here if you would like to use hard disks under Linux which - were partitioned using Windows 2000's or XP's Logical Disk Manager. - They are also known as "Dynamic Disks". + were partitioned using Windows 2000's/XP's or Vista's Logical Disk + Manager. They are also known as "Dynamic Disks". + + Note this driver only supports Dynamic Disks with a protective MBR + label, i.e. DOS partition table. It does not support GPT labelled + Dynamic Disks yet as can be created with Vista. Windows 2000 introduced the concept of Dynamic Disks to get around the limitations of the PC's partitioning scheme. The Logical Disk @@ -175,8 +179,8 @@ config LDM_PARTITION mirrored, striped or RAID volumes, all without the need for rebooting. - Normal partitions are now called Basic Disks under Windows 2000 and - XP. + Normal partitions are now called Basic Disks under Windows 2000, XP, + and Vista. For a fuller description read . diff --git a/fs/partitions/ldm.c b/fs/partitions/ldm.c index 1a60926..c387812 100644 --- a/fs/partitions/ldm.c +++ b/fs/partitions/ldm.c @@ -2,10 +2,10 @@ * ldm - Support for Windows Logical Disk Manager (Dynamic Disks) * * Copyright (C) 2001,2002 Richard Russon - * Copyright (c) 2001-2004 Anton Altaparmakov + * Copyright (c) 2001-2007 Anton Altaparmakov * Copyright (C) 2001,2002 Jakob Kemi * - * Documentation is available at http://linux-ntfs.sf.net/ldm + * Documentation is available at http://www.linux-ntfs.org/content/view/19/37/ * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software @@ -62,7 +62,6 @@ static void _ldm_printk (const char *level, const char *function, printk ("%s%s(): %s\n", level, function, buf); } - /** * ldm_parse_hexbyte - Convert a ASCII hex number to a byte * @src: Pointer to at least 2 characters to convert. @@ -118,7 +117,6 @@ static bool ldm_parse_guid (const u8 *src, u8 *dest) return true; } - /** * ldm_parse_privhead - Read the LDM Database PRIVHEAD structure * @data: Raw database PRIVHEAD structure loaded from the device @@ -130,46 +128,48 @@ static bool ldm_parse_guid (const u8 *src, u8 *dest) * Return: 'true' @ph contains the PRIVHEAD data * 'false' @ph contents are undefined */ -static bool ldm_parse_privhead (const u8 *data, struct privhead *ph) +static bool ldm_parse_privhead(const u8 *data, struct privhead *ph) { - BUG_ON (!data || !ph); + bool is_vista = false; - if (MAGIC_PRIVHEAD != BE64 (data)) { - ldm_error ("Cannot find PRIVHEAD structure. LDM database is" + BUG_ON(!data || !ph); + if (MAGIC_PRIVHEAD != BE64(data)) { + ldm_error("Cannot find PRIVHEAD structure. LDM database is" " corrupt. Aborting."); return false; } - - ph->ver_major = BE16 (data + 0x000C); - ph->ver_minor = BE16 (data + 0x000E); - ph->logical_disk_start = BE64 (data + 0x011B); - ph->logical_disk_size = BE64 (data + 0x0123); - ph->config_start = BE64 (data + 0x012B); - ph->config_size = BE64 (data + 0x0133); - - if ((ph->ver_major != 2) || (ph->ver_minor != 11)) { - ldm_error ("Expected PRIVHEAD version %d.%d, got %d.%d." - " Aborting.", 2, 11, ph->ver_major, ph->ver_minor); + ph->ver_major = BE16(data + 0x000C); + ph->ver_minor = BE16(data + 0x000E); + ph->logical_disk_start = BE64(data + 0x011B); + ph->logical_disk_size = BE64(data + 0x0123); + ph->config_start = BE64(data + 0x012B); + ph->config_size = BE64(data + 0x0133); + /* Version 2.11 is Win2k/XP and version 2.12 is Vista. */ + if (ph->ver_major == 2 && ph->ver_minor == 12) + is_vista = true; + if (!is_vista && (ph->ver_major != 2 || ph->ver_minor != 11)) { + ldm_error("Expected PRIVHEAD version 2.11 or 2.12, got %d.%d." + " Aborting.", ph->ver_major, ph->ver_minor); return false; } + ldm_debug("PRIVHEAD version %d.%d (Windows %s).", ph->ver_major, + ph->ver_minor, is_vista ? "Vista" : "2000/XP"); if (ph->config_size != LDM_DB_SIZE) { /* 1 MiB in sectors. */ - /* Warn the user and continue, carefully */ - ldm_info ("Database is normally %u bytes, it claims to " + /* Warn the user and continue, carefully. */ + ldm_info("Database is normally %u bytes, it claims to " "be %llu bytes.", LDM_DB_SIZE, - (unsigned long long)ph->config_size ); + udunsigned long long)ph->config_size); } - if ((ph->logical_disk_size == 0) || - (ph->logical_disk_start + ph->logical_disk_size > ph->config_start)) { - ldm_error ("PRIVHEAD disk size doesn't match real disk size"); + if ((ph->logical_disk_size == 0) || (ph->logical_disk_start + + ph->logical_disk_size > ph->config_start)) { + ldm_error("PRIVHEAD disk size doesn't match real disk size"); return false; } - - if (!ldm_parse_guid (data + 0x0030, ph->disk_id)) { - ldm_error ("PRIVHEAD contains an invalid GUID."); + if (!ldm_parse_guid(data + 0x0030, ph->disk_id)) { + ldm_error("PRIVHEAD contains an invalid GUID."); return false; } - - ldm_debug ("Parsed PRIVHEAD successfully."); + ldm_debug("Parsed PRIVHEAD successfully."); return true; } @@ -409,7 +409,7 @@ out: * Return: 'true' @toc1 contains validated TOCBLOCK info * 'false' @toc1 contents are undefined */ -static bool ldm_validate_tocblocks (struct block_device *bdev, +static bool ldm_validate_tocblocks(struct block_device *bdev, unsigned long base, struct ldmdb *ldb) { static const int off[4] = { OFF_TOCB1, OFF_TOCB2, OFF_TOCB3, OFF_TOCB4}; @@ -417,54 +417,57 @@ static bool ldm_validate_tocblocks (struct block_device *bdev, struct privhead *ph; Sector sect; u8 *data; + int i, nr_tbs; bool result = false; - int i; - BUG_ON (!bdev || !ldb); - - ph = &ldb->ph; + BUG_ON(!bdev || !ldb); + ph = &ldb->ph; tb[0] = &ldb->toc; - tb[1] = kmalloc (sizeof (*tb[1]), GFP_KERNEL); - tb[2] = kmalloc (sizeof (*tb[2]), GFP_KERNEL); - tb[3] = kmalloc (sizeof (*tb[3]), GFP_KERNEL); - if (!tb[1] || !tb[2] || !tb[3]) { - ldm_crit ("Out of memory."); - goto out; + tb[1] = kmalloc(sizeof(*tb[1]) * 3, GFP_KERNEL); + if (!tb[1]) { + ldm_crit("Out of memory."); + goto err; } - - for (i = 0; i < 4; i++) /* Read and parse all four toc's. */ - { - data = read_dev_sector (bdev, base + off[i], §); + tb[2] = (struct tocblock*)((u8*)tb[1] + sizeof(*tb[1])); + tb[3] = (struct tocblock*)((u8*)tb[2] + sizeof(*tb[2])); + /* + * Try to read and parse all four TOCBLOCKs. + * + * Windows Vista LDM v2.12 does not always have all four TOCBLOCKs so + * skip any that fail as long as we get at least one valid TOCBLOCK. + */ + for (nr_tbs = i = 0; i < 4; i++) { + data = read_dev_sector(bdev, base + off[i], §); if (!data) { - ldm_crit ("Disk read failed."); - goto out; + ldm_error("Disk read failed for TOCBLOCK %d.", i); + continue; } - result = ldm_parse_tocblock (data, tb[i]); - put_dev_sector (sect); - if (!result) - goto out; /* Already logged */ + if (ldm_parse_tocblock(data, tb[nr_tbs])) + nr_tbs++; + put_dev_sector(sect); } - - /* Range check the toc against a privhead. */ + if (!nr_tbs) { + ldm_crit("Failed to find a valid TOCBLOCK."); + goto err; + } + /* Range check the TOCBLOCK against a privhead. */ if (((tb[0]->bitmap1_start + tb[0]->bitmap1_size) > ph->config_size) || - ((tb[0]->bitmap2_start + tb[0]->bitmap2_size) > ph->config_size)) { - ldm_crit ("The bitmaps are out of range. Giving up."); - goto out; + ((tb[0]->bitmap2_start + tb[0]->bitmap2_size) > + ph->config_size)) { + ldm_crit("The bitmaps are out of range. Giving up."); + goto err; } - - if (!ldm_compare_tocblocks (tb[0], tb[1]) || /* Compare all tocs. */ - !ldm_compare_tocblocks (tb[0], tb[2]) || - !ldm_compare_tocblocks (tb[0], tb[3])) { - ldm_crit ("The TOCBLOCKs don't match."); - goto out; + /* Compare all loaded TOCBLOCKs. */ + for (i = 1; i < nr_tbs; i++) { + if (!ldm_compare_tocblocks(tb[0], tb[i])) { + ldm_crit("TOCBLOCKs 0 and %d do not match.", i); + goto err; + } } - - ldm_debug ("Validated TOCBLOCKs successfully."); + ldm_debug("Validated %d TOCBLOCKs successfully.", nr_tbs); result = true; -out: - kfree (tb[1]); - kfree (tb[2]); - kfree (tb[3]); +err: + kfree(tb[1]); return result; } @@ -566,7 +569,7 @@ static bool ldm_validate_partition_table (struct block_device *bdev) p = (struct partition*)(data + 0x01BE); for (i = 0; i < 4; i++, p++) - if (SYS_IND (p) == WIN2K_DYNAMIC_PARTITION) { + if (SYS_IND (p) == LDM_PARTITION) { result = true; break; } @@ -975,44 +978,68 @@ static bool ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) * Return: 'true' @vb contains a Partition VBLK * 'false' @vb contents are not defined */ -static bool ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_prt3(const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, r_size, r_parent, r_diskid, r_index, len; struct vblk_part *part; - BUG_ON (!buffer || !vb); - - r_objid = ldm_relative (buffer, buflen, 0x18, 0); - r_name = ldm_relative (buffer, buflen, 0x18, r_objid); - r_size = ldm_relative (buffer, buflen, 0x34, r_name); - r_parent = ldm_relative (buffer, buflen, 0x34, r_size); - r_diskid = ldm_relative (buffer, buflen, 0x34, r_parent); - + BUG_ON(!buffer || !vb); + r_objid = ldm_relative(buffer, buflen, 0x18, 0); + if (r_objid < 0) { + ldm_error("r_objid %d < 0", r_objid); + return false; + } + r_name = ldm_relative(buffer, buflen, 0x18, r_objid); + if (r_name < 0) { + ldm_error("r_name %d < 0", r_name); + return false; + } + r_size = ldm_relative(buffer, buflen, 0x34, r_name); + if (r_size < 0) { + ldm_error("r_size %d < 0", r_size); + return false; + } + r_parent = ldm_relative(buffer, buflen, 0x34, r_size); + if (r_parent < 0) { + ldm_error("r_parent %d < 0", r_parent); + return false; + } + r_diskid = ldm_relative(buffer, buflen, 0x34, r_parent); + if (r_diskid < 0) { + ldm_error("r_diskid %d < 0", r_diskid); + return false; + } if (buffer[0x12] & VBLK_FLAG_PART_INDEX) { - r_index = ldm_relative (buffer, buflen, 0x34, r_diskid); + r_index = ldm_relative(buffer, buflen, 0x34, r_diskid); + if (r_index < 0) { + ldm_error("r_index %d < 0", r_index); + return false; + } len = r_index; } else { r_index = 0; len = r_diskid; } - if (len < 0) + if (len < 0) { + ldm_error("len %d < 0", len); return false; - + } len += VBLK_SIZE_PRT3; - if (len != BE32 (buffer + 0x14)) + if (len > BE32(buffer + 0x14)) { + ldm_error("len %d > BE32(buffer + 0x14) %d", len, + BE32(buffer + 0x14)); return false; - + } part = &vb->vblk.part; - part->start = BE64 (buffer + 0x24 + r_name); - part->volume_offset = BE64 (buffer + 0x2C + r_name); - part->size = ldm_get_vnum (buffer + 0x34 + r_name); - part->parent_id = ldm_get_vnum (buffer + 0x34 + r_size); - part->disk_id = ldm_get_vnum (buffer + 0x34 + r_parent); + part->start = BE64(buffer + 0x24 + r_name); + part->volume_offset = BE64(buffer + 0x2C + r_name); + part->size = ldm_get_vnum(buffer + 0x34 + r_name); + part->parent_id = ldm_get_vnum(buffer + 0x34 + r_size); + part->disk_id = ldm_get_vnum(buffer + 0x34 + r_parent); if (vb->flags & VBLK_FLAG_PART_INDEX) part->partnum = buffer[0x35 + r_diskid]; else part->partnum = 0; - return true; } @@ -1475,4 +1502,3 @@ out: kfree (ldb); return result; } - diff --git a/fs/partitions/ldm.h b/fs/partitions/ldm.h index 6e8d795..d2e6a30 100644 --- a/fs/partitions/ldm.h +++ b/fs/partitions/ldm.h @@ -2,10 +2,10 @@ * ldm - Part of the Linux-NTFS project. * * Copyright (C) 2001,2002 Richard Russon - * Copyright (C) 2001 Anton Altaparmakov + * Copyright (c) 2001-2007 Anton Altaparmakov * Copyright (C) 2001,2002 Jakob Kemi * - * Documentation is available at http://linux-ntfs.sf.net/ldm + * Documentation is available at http://www.linux-ntfs.org/content/view/19/37/ * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -93,7 +93,7 @@ struct parsed_partitions; #define OFF_VMDB 17 /* List of partitions. */ -#define WIN2K_DYNAMIC_PARTITION 0x42 /* Formerly SFS (Landis). */ +#define LDM_PARTITION 0x42 /* Formerly SFS (Landis). */ #define TOC_BITMAP1 "config" /* Names of the two defined */ #define TOC_BITMAP2 "log" /* bitmaps in the TOCBLOCK. */ -- cgit v1.1 From 72dd9ca59944f117c719a1cc3fc9010bce0486f2 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 22 May 2007 00:28:11 -0400 Subject: partitions/LDM: build fix This from a "tested" patch... Signed-off-by: Jeff Garzik Cc: Anton Altaparmakov Signed-off-by: Linus Torvalds --- fs/partitions/ldm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/partitions/ldm.c b/fs/partitions/ldm.c index c387812..99873a2 100644 --- a/fs/partitions/ldm.c +++ b/fs/partitions/ldm.c @@ -158,7 +158,7 @@ static bool ldm_parse_privhead(const u8 *data, struct privhead *ph) /* Warn the user and continue, carefully. */ ldm_info("Database is normally %u bytes, it claims to " "be %llu bytes.", LDM_DB_SIZE, - udunsigned long long)ph->config_size); + (unsigned long long)ph->config_size); } if ((ph->logical_disk_size == 0) || (ph->logical_disk_start + ph->logical_disk_size > ph->config_start)) { -- cgit v1.1 From b9ba347f27f2508e3da023688d047e111cbbe2da Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 23 May 2007 13:57:32 -0700 Subject: fuse: fix mknod of regular file The wrong lookup flag was tested in ->create() causing havoc (error or Oops) when a regular file was created with mknod() in a fuse filesystem. Thanks to J. Cameijo Cerdeira for the report. Kernels 2.6.18 onward are affected. Please apply to -stable as well. Signed-off-by: Miklos Szeredi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fuse/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8890eba..bd5a772 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -485,7 +485,7 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode, static int fuse_create(struct inode *dir, struct dentry *entry, int mode, struct nameidata *nd) { - if (nd && (nd->flags & LOOKUP_CREATE)) { + if (nd && (nd->flags & LOOKUP_OPEN)) { int err = fuse_create_open(dir, entry, mode, nd); if (err != -ENOSYS) return err; -- cgit v1.1 From 6087b2dab2c914268b1a50882edbbad82bfefd29 Mon Sep 17 00:00:00 2001 From: Badari Pulavarty Date: Wed, 23 May 2007 13:57:45 -0700 Subject: optimize compat_core_sys_select() by a using stack space for small fd sets Optimize select by a using stack space for small fd sets. core_sys_select() already has this optimization. This is for compat version. Signed-off-by: Badari Pulavarty Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/compat.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'fs') diff --git a/fs/compat.c b/fs/compat.c index 1de2331..4db6216 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1544,9 +1544,10 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout) { fd_set_bits fds; - char *bits; + void *bits; int size, max_fds, ret = -EINVAL; struct fdtable *fdt; + long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; if (n < 0) goto out_nofds; @@ -1564,11 +1565,14 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, * since we used fdset we need to allocate memory in units of * long-words. */ - ret = -ENOMEM; size = FDS_BYTES(n); - bits = kmalloc(6 * size, GFP_KERNEL); - if (!bits) - goto out_nofds; + bits = stack_fds; + if (size > sizeof(stack_fds) / 6) { + bits = kmalloc(6 * size, GFP_KERNEL); + ret = -ENOMEM; + if (!bits) + goto out_nofds; + } fds.in = (unsigned long *) bits; fds.out = (unsigned long *) (bits + size); fds.ex = (unsigned long *) (bits + 2*size); @@ -1600,7 +1604,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, compat_set_fd_set(n, exp, fds.res_ex)) ret = -EFAULT; out: - kfree(bits); + if (bits != stack_fds) + kfree(bits); out_nofds: return ret; } -- cgit v1.1 From 5a1b63914815e4223ceb3d079286e18f9ee92b4b Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 23 May 2007 13:57:52 -0700 Subject: Missing 'const' from reiserfs MIN_KEY declaration. In stree.c, MIN_KEY is declared const. The extern declaration in dir.c doesn't match... Signed-off-by: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 9c23fee..ffbfc2c 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -10,7 +10,7 @@ #include #include -extern struct reiserfs_key MIN_KEY; +extern const struct reiserfs_key MIN_KEY; static int reiserfs_readdir(struct file *, void *, filldir_t); static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, -- cgit v1.1 From 492c8b332e3af279ffadf49b85967d5e43810923 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 23 May 2007 13:57:53 -0700 Subject: uselib: add missing MNT_NOEXEC check We don't allow loading ELF shared library from noexec points so the same should apply to sys_uselib aswell. Signed-off-by: Christoph Hellwig Cc: Ulrich Drepper Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/exec.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'fs') diff --git a/fs/exec.c b/fs/exec.c index 0b68588..f20561f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -134,6 +134,9 @@ asmlinkage long sys_uselib(const char __user * library) if (error) goto out; + error = -EACCES; + if (nd.mnt->mnt_flags & MNT_NOEXEC) + goto exit; error = -EINVAL; if (!S_ISREG(nd.dentry->d_inode->i_mode)) goto exit; -- cgit v1.1 From 889f784831d6cc9125a74eb55a5641f95635a204 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 23 May 2007 13:57:54 -0700 Subject: fuse: generic_write_checks() for direct_io This fixes O_APPEND in direct IO mode. Also checks writes against file size limits, notably rlimits. Reported by Greg Bruno. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fuse/file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/fuse/file.c b/fs/fuse/file.c index d0ed60b..adf7995 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -610,7 +610,9 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, ssize_t res; /* Don't allow parallel writes to the same file */ mutex_lock(&inode->i_mutex); - res = fuse_direct_io(file, buf, count, ppos, 1); + res = generic_write_checks(file, ppos, &count, 0); + if (!res) + res = fuse_direct_io(file, buf, count, ppos, 1); mutex_unlock(&inode->i_mutex); return res; } -- cgit v1.1 From ead5f0b5fa41dd3649a44bfc922d06641ff3dbcf Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 23 May 2007 13:57:54 -0700 Subject: fuse: delete inode on drop When inode is dropped (no more references) delete it from cache. There's not much point in keeping it cached, when a new lookup will refresh the attributes anyway. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fuse/inode.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 78f7a1d..9804c0c 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -454,6 +454,7 @@ static const struct super_operations fuse_super_operations = { .destroy_inode = fuse_destroy_inode, .read_inode = fuse_read_inode, .clear_inode = fuse_clear_inode, + .drop_inode = generic_delete_inode, .remount_fs = fuse_remount_fs, .put_super = fuse_put_super, .umount_begin = fuse_umount_begin, -- cgit v1.1 From b3762bfc8d046342db664d855f8f875e8a4c2ca1 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 23 May 2007 13:58:04 -0700 Subject: signalfd: retrieve multiple signals with one read() call Gathering signals in bulk enables server applications to drain a signal queue (almost full of realtime signals) more efficiently by reducing the syscall and file look-up overhead. Very similar to the sigtimedwait4() call described by Niels Provos, Chuck Lever, and Stephen Tweedie in a paper entitled "Analyzing the Overload Behavior of a Simple Web Server". The paper lists more details and advantages. Signed-off-by: Davi E. M. Arnaut Acked-by: Davide Libenzi Cc: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/signalfd.c | 120 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 75 insertions(+), 45 deletions(-) (limited to 'fs') diff --git a/fs/signalfd.c b/fs/signalfd.c index 7cfeab4..f1da892 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -11,6 +11,8 @@ * Now using anonymous inode source. * Thanks to Oleg Nesterov for useful code review and suggestions. * More comments and suggestions from Arnd Bergmann. + * Sat May 19, 2007: Davi E. M. Arnaut + * Retrieve multiple signals with one read() call */ #include @@ -206,6 +208,59 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, return err ? -EFAULT: sizeof(*uinfo); } +static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, siginfo_t *info, + int nonblock) +{ + ssize_t ret; + struct signalfd_lockctx lk; + DECLARE_WAITQUEUE(wait, current); + + if (!signalfd_lock(ctx, &lk)) + return 0; + + ret = dequeue_signal(lk.tsk, &ctx->sigmask, info); + switch (ret) { + case 0: + if (!nonblock) + break; + ret = -EAGAIN; + default: + signalfd_unlock(&lk); + return ret; + } + + add_wait_queue(&ctx->wqh, &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + ret = dequeue_signal(lk.tsk, &ctx->sigmask, info); + signalfd_unlock(&lk); + if (ret != 0) + break; + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + schedule(); + ret = signalfd_lock(ctx, &lk); + if (unlikely(!ret)) { + /* + * Let the caller read zero byte, ala socket + * recv() when the peer disconnect. This test + * must be done before doing a dequeue_signal(), + * because if the sighand has been orphaned, + * the dequeue_signal() call is going to crash + * because ->sighand will be long gone. + */ + break; + } + } + + remove_wait_queue(&ctx->wqh, &wait); + __set_current_state(TASK_RUNNING); + + return ret; +} + /* * Returns either the size of a "struct signalfd_siginfo", or zero if the * sighand we are attached to, has been orphaned. The "count" parameter @@ -215,55 +270,30 @@ static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct signalfd_ctx *ctx = file->private_data; - ssize_t res = 0; - int locked, signo; + struct signalfd_siginfo __user *siginfo; + int nonblock = file->f_flags & O_NONBLOCK; + ssize_t ret, total = 0; siginfo_t info; - struct signalfd_lockctx lk; - DECLARE_WAITQUEUE(wait, current); - if (count < sizeof(struct signalfd_siginfo)) + count /= sizeof(struct signalfd_siginfo); + if (!count) return -EINVAL; - locked = signalfd_lock(ctx, &lk); - if (!locked) - return 0; - res = -EAGAIN; - signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info); - if (signo == 0 && !(file->f_flags & O_NONBLOCK)) { - add_wait_queue(&ctx->wqh, &wait); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info); - if (signo != 0) - break; - if (signal_pending(current)) { - res = -ERESTARTSYS; - break; - } - signalfd_unlock(&lk); - schedule(); - locked = signalfd_lock(ctx, &lk); - if (unlikely(!locked)) { - /* - * Let the caller read zero byte, ala socket - * recv() when the peer disconnect. This test - * must be done before doing a dequeue_signal(), - * because if the sighand has been orphaned, - * the dequeue_signal() call is going to crash. - */ - res = 0; - break; - } - } - remove_wait_queue(&ctx->wqh, &wait); - __set_current_state(TASK_RUNNING); - } - if (likely(locked)) - signalfd_unlock(&lk); - if (likely(signo)) - res = signalfd_copyinfo((struct signalfd_siginfo __user *) buf, - &info); - return res; + siginfo = (struct signalfd_siginfo __user *) buf; + + do { + ret = signalfd_dequeue(ctx, &info, nonblock); + if (unlikely(ret <= 0)) + break; + ret = signalfd_copyinfo(siginfo, &info); + if (ret < 0) + break; + siginfo++; + total += ret; + nonblock = 1; + } while (--count); + + return total ? total : ret; } static const struct file_operations signalfd_fops = { -- cgit v1.1 From 53a2731f9310a66beaf55677229ab067c85ce4fa Mon Sep 17 00:00:00 2001 From: Michael Halcrow Date: Wed, 23 May 2007 13:58:15 -0700 Subject: eCryptfs: delay writing 0's after llseek until write Delay writing 0's out in eCryptfs after a seek past the end of the file until data is actually written. http://www.opengroup.org/onlinepubs/009695399/functions/lseek.html ``The lseek() function shall not, by itself, extend the size of a file.'' Without this fix, applications that lseek() past the end of the file without writing will experience unexpected behavior. Signed-off-by: Michael Halcrow Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ecryptfs/file.c | 59 +----------------------------------------------------- fs/ecryptfs/mmap.c | 38 ++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 61 deletions(-) (limited to 'fs') diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 9881b5c..59288d8 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -33,63 +33,6 @@ #include "ecryptfs_kernel.h" /** - * ecryptfs_llseek - * @file: File we are seeking in - * @offset: The offset to seek to - * @origin: 2 - offset from i_size; 1 - offset from f_pos - * - * Returns the position we have seeked to, or negative on error - */ -static loff_t ecryptfs_llseek(struct file *file, loff_t offset, int origin) -{ - loff_t rv; - loff_t new_end_pos; - int rc; - int expanding_file = 0; - struct inode *inode = file->f_mapping->host; - - /* If our offset is past the end of our file, we're going to - * need to grow it so we have a valid length of 0's */ - new_end_pos = offset; - switch (origin) { - case 2: - new_end_pos += i_size_read(inode); - expanding_file = 1; - break; - case 1: - new_end_pos += file->f_pos; - if (new_end_pos > i_size_read(inode)) { - ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) " - "> i_size_read(inode)(=[0x%.16x])\n", - new_end_pos, i_size_read(inode)); - expanding_file = 1; - } - break; - default: - if (new_end_pos > i_size_read(inode)) { - ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) " - "> i_size_read(inode)(=[0x%.16x])\n", - new_end_pos, i_size_read(inode)); - expanding_file = 1; - } - } - ecryptfs_printk(KERN_DEBUG, "new_end_pos = [0x%.16x]\n", new_end_pos); - if (expanding_file) { - rc = ecryptfs_truncate(file->f_path.dentry, new_end_pos); - if (rc) { - rv = rc; - ecryptfs_printk(KERN_ERR, "Error on attempt to " - "truncate to (higher) offset [0x%.16x];" - " rc = [%d]\n", new_end_pos, rc); - goto out; - } - } - rv = generic_file_llseek(file, offset, origin); -out: - return rv; -} - -/** * ecryptfs_read_update_atime * * generic_file_read updates the atime of upper layer inode. But, it @@ -425,7 +368,7 @@ const struct file_operations ecryptfs_dir_fops = { }; const struct file_operations ecryptfs_main_fops = { - .llseek = ecryptfs_llseek, + .llseek = generic_file_llseek, .read = do_sync_read, .aio_read = ecryptfs_read_update_atime, .write = do_sync_write, diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 88ea669..55cec98 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -376,9 +376,31 @@ out: return 0; } +/** + * eCryptfs does not currently support holes. When writing after a + * seek past the end of the file, eCryptfs fills in 0's through to the + * current location. The code to fill in the 0's to all the + * intermediate pages calls ecryptfs_prepare_write_no_truncate(). + */ +static int +ecryptfs_prepare_write_no_truncate(struct file *file, struct page *page, + unsigned from, unsigned to) +{ + int rc = 0; + + if (from == 0 && to == PAGE_CACHE_SIZE) + goto out; /* If we are writing a full page, it will be + up to date. */ + if (!PageUptodate(page)) + rc = ecryptfs_do_readpage(file, page, page->index); +out: + return rc; +} + static int ecryptfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { + loff_t pos; int rc = 0; if (from == 0 && to == PAGE_CACHE_SIZE) @@ -386,6 +408,16 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, up to date. */ if (!PageUptodate(page)) rc = ecryptfs_do_readpage(file, page, page->index); + pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; + if (pos > i_size_read(page->mapping->host)) { + rc = ecryptfs_truncate(file->f_path.dentry, pos); + if (rc) { + printk(KERN_ERR "Error on attempt to " + "truncate to (higher) offset [%lld];" + " rc = [%d]\n", pos, rc); + goto out; + } + } out: return rc; } @@ -744,10 +776,10 @@ int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) rc = PTR_ERR(tmp_page); goto out; } - rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros); - if (rc) { + if ((rc = ecryptfs_prepare_write_no_truncate(file, tmp_page, start, + (start + num_zeros)))) { ecryptfs_printk(KERN_ERR, "Error preparing to write zero's " - "to remainder of page at index [0x%.16x]\n", + "to page at index [0x%.16x]\n", index); page_cache_release(tmp_page); goto out; -- cgit v1.1 From 7fe7f8487ae742239dd8c66596e2311c30d057d1 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 20 May 2007 10:18:27 -0400 Subject: NFS: Avoid a deadlock situation on write When processes are allowed to attempt to lock a non-contiguous range of nfs write requests, it is possible for generic_writepages to 'wrap round' the address space, and call writepage() on a request that is already locked by the same process. We avoid the deadlock by checking if the page index is contiguous with the list of nfs write requests that is already held in our nfs_pageio_descriptor prior to attempting to lock a new request. Signed-off-by: Trond Myklebust --- fs/nfs/pagelist.c | 20 ++++++++++++++++++++ fs/nfs/write.c | 6 ++++-- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index cbdd1c6..c5bb51a 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -355,6 +355,26 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc) nfs_pageio_doio(desc); } +/** + * nfs_pageio_cond_complete - Conditional I/O completion + * @desc: pointer to io descriptor + * @index: page index + * + * It is important to ensure that processes don't try to take locks + * on non-contiguous ranges of pages as that might deadlock. This + * function should be called before attempting to wait on a locked + * nfs_page. It will complete the I/O if the page index 'index' + * is not contiguous with the existing list of pages in 'desc'. + */ +void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index) +{ + if (!list_empty(&desc->pg_list)) { + struct nfs_page *prev = nfs_list_entry(desc->pg_list.prev); + if (index != prev->wb_index + 1) + nfs_pageio_doio(desc); + } +} + #define NFS_SCAN_MAXENTRIES 16 /** * nfs_scan_list - Scan a list for matching requests diff --git a/fs/nfs/write.c b/fs/nfs/write.c index b084c03..af344a15 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -273,8 +273,6 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, * request as dirty (in which case we don't care). */ spin_unlock(req_lock); - /* Prevent deadlock! */ - nfs_pageio_complete(pgio); ret = nfs_wait_on_request(req); nfs_release_request(req); if (ret != 0) @@ -321,6 +319,8 @@ static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc pgio = &mypgio; } + nfs_pageio_cond_complete(pgio, page->index); + err = nfs_page_async_flush(pgio, page); if (err <= 0) goto out; @@ -329,6 +329,8 @@ static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc if (!offset) goto out; + nfs_pageio_cond_complete(pgio, page->index); + ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE); if (ctx == NULL) { err = -EBADF; -- cgit v1.1 From 749e146e01cf87ce3c1d6f6077b877471b04df5b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 19 May 2007 17:22:46 -0400 Subject: NFS: Fix handful of compiler warnings in direct.c This patch fixes a couple of signage issues that were causing an Oops when running the LTP diotest4 test. get_user_pages() returns a signed error, hence we need to be careful when comparing with the unsigned number of pages from data->npages. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'fs') diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 345aa5c..6c588ec 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -122,9 +122,9 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_ return -EINVAL; } -static void nfs_direct_dirty_pages(struct page **pages, int npages) +static void nfs_direct_dirty_pages(struct page **pages, unsigned int npages) { - int i; + unsigned int i; for (i = 0; i < npages; i++) { struct page *page = pages[i]; if (!PageCompound(page)) @@ -132,9 +132,9 @@ static void nfs_direct_dirty_pages(struct page **pages, int npages) } } -static void nfs_direct_release_pages(struct page **pages, int npages) +static void nfs_direct_release_pages(struct page **pages, unsigned int npages) { - int i; + unsigned int i; for (i = 0; i < npages; i++) page_cache_release(pages[i]); } @@ -279,9 +279,12 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo result = get_user_pages(current, current->mm, user_addr, data->npages, 1, 0, data->pagevec, NULL); up_read(¤t->mm->mmap_sem); - if (unlikely(result < data->npages)) { - if (result > 0) - nfs_direct_release_pages(data->pagevec, result); + if (result < 0) { + nfs_readdata_release(data); + break; + } + if ((unsigned)result < data->npages) { + nfs_direct_release_pages(data->pagevec, result); nfs_readdata_release(data); break; } @@ -610,9 +613,12 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l result = get_user_pages(current, current->mm, user_addr, data->npages, 0, 0, data->pagevec, NULL); up_read(¤t->mm->mmap_sem); - if (unlikely(result < data->npages)) { - if (result > 0) - nfs_direct_release_pages(data->pagevec, result); + if (result < 0) { + nfs_writedata_release(data); + break; + } + if ((unsigned)result < data->npages) { + nfs_direct_release_pages(data->pagevec, result); nfs_writedata_release(data); break; } -- cgit v1.1 From d4a8f3677fe2c2fc86443254fe42825e244c194d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 22 May 2007 10:22:27 -0400 Subject: NFS: Fix nfs_direct_dirty_pages() We only need to dirty the pages that were actually read in. Also convert nfs_direct_dirty_pages() to call set_page_dirty() instead of set_page_dirty_lock(). A call to lock_page() is unacceptable in an rpciod callback function. Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'fs') diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 6c588ec..0c542ec 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -122,13 +122,19 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_ return -EINVAL; } -static void nfs_direct_dirty_pages(struct page **pages, unsigned int npages) +static void nfs_direct_dirty_pages(struct page **pages, unsigned int pgbase, size_t count) { + unsigned int npages; unsigned int i; + + if (count == 0) + return; + pages += (pgbase >> PAGE_SHIFT); + npages = (count + (pgbase & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT; for (i = 0; i < npages; i++) { struct page *page = pages[i]; if (!PageCompound(page)) - set_page_dirty_lock(page); + set_page_dirty(page); } } @@ -224,17 +230,18 @@ static void nfs_direct_read_result(struct rpc_task *task, void *calldata) if (nfs_readpage_result(task, data) != 0) return; - nfs_direct_dirty_pages(data->pagevec, data->npages); - nfs_direct_release_pages(data->pagevec, data->npages); - spin_lock(&dreq->lock); - - if (likely(task->tk_status >= 0)) - dreq->count += data->res.count; - else + if (unlikely(task->tk_status < 0)) { dreq->error = task->tk_status; - - spin_unlock(&dreq->lock); + spin_unlock(&dreq->lock); + } else { + dreq->count += data->res.count; + spin_unlock(&dreq->lock); + nfs_direct_dirty_pages(data->pagevec, + data->args.pgbase, + data->res.count); + } + nfs_direct_release_pages(data->pagevec, data->npages); if (put_dreq(dreq)) nfs_direct_complete(dreq); -- cgit v1.1 From e9dfc0b2bc42761410e8db6c252c6c5889e178b8 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Mon, 14 May 2007 11:38:51 -0700 Subject: ocfs2: trylock in ocfs2_readpage() Similarly to the page lock / cluster lock inversion in ocfs2_readpage, we can deadlock on ip_alloc_sem. We can down_read_trylock() instead and just return AOP_TRUNCATED_PAGE if the operation fails. Signed-off-by: Mark Fasheh --- fs/ocfs2/aops.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 8e7cafb5..3030670 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -222,7 +222,10 @@ static int ocfs2_readpage(struct file *file, struct page *page) goto out; } - down_read(&OCFS2_I(inode)->ip_alloc_sem); + if (down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem) == 0) { + ret = AOP_TRUNCATED_PAGE; + goto out_meta_unlock; + } /* * i_size might have just been updated as we grabed the meta lock. We @@ -258,6 +261,7 @@ static int ocfs2_readpage(struct file *file, struct page *page) ocfs2_data_unlock(inode, 0); out_alloc: up_read(&OCFS2_I(inode)->ip_alloc_sem); +out_meta_unlock: ocfs2_meta_unlock(inode, 0); out: if (unlock) -- cgit v1.1 From 1024c902abdcbd2425aa850d7ef04e013ffb35f0 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Mon, 14 May 2007 11:39:40 -0700 Subject: ocfs2: unmap_mapping_range() in ocfs2_truncate() We weren't calling this before, but since ocfs2 handles the entire truncate operation, we should. Signed-off-by: Mark Fasheh --- fs/ocfs2/file.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 9395b4f..d459eb9 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -326,6 +326,7 @@ static int ocfs2_truncate_file(struct inode *inode, (unsigned long long)OCFS2_I(inode)->ip_blkno, (unsigned long long)new_i_size); + unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); truncate_inode_pages(inode->i_mapping, new_i_size); fe = (struct ocfs2_dinode *) di_bh->b_data; -- cgit v1.1 From 5c3c6bb7709bf2bf4132750124879b3d89183e46 Mon Sep 17 00:00:00 2001 From: Nate Diller Date: Thu, 10 May 2007 22:56:01 -0700 Subject: [PATCH] ocfs2: use zero_user_page Use zero_user_page() instead of open-coding it. Signed-off-by: Nate Diller Signed-off-by: Andrew Morton Signed-off-by: Mark Fasheh --- fs/ocfs2/aops.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 3030670..0023b31 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -238,10 +238,7 @@ static int ocfs2_readpage(struct file *file, struct page *page) * XXX sys_readahead() seems to get that wrong? */ if (start >= i_size_read(inode)) { - char *addr = kmap(page); - memset(addr, 0, PAGE_SIZE); - flush_dcache_page(page); - kunmap(page); + zero_user_page(page, 0, PAGE_SIZE, KM_USER0); SetPageUptodate(page); ret = 0; goto out_alloc; -- cgit v1.1 From 8fccfc829a66b8b879c6672940523a402a786ce1 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Wed, 9 May 2007 17:34:26 -0700 Subject: ocfs2: fix inode leak We weren't cleaning up our inode reference on error in ocfs2_reserve_local_alloc_bits(). Add a check for error return and iput() if need be. Move the code to set the alloc context inode info to the end of the function so we don't have any possibility of passing back a bad pointer. Signed-off-by: Mark Fasheh --- fs/ocfs2/localalloc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 4dedd97..545f789 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c @@ -471,9 +471,6 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, mutex_lock(&local_alloc_inode->i_mutex); - ac->ac_inode = local_alloc_inode; - ac->ac_which = OCFS2_AC_USE_LOCAL; - if (osb->local_alloc_state != OCFS2_LA_ENABLED) { status = -ENOSPC; goto bail; @@ -511,10 +508,14 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, } } + ac->ac_inode = local_alloc_inode; + ac->ac_which = OCFS2_AC_USE_LOCAL; get_bh(osb->local_alloc_bh); ac->ac_bh = osb->local_alloc_bh; status = 0; bail: + if (status < 0 && local_alloc_inode) + iput(local_alloc_inode); mlog_exit(status); return status; -- cgit v1.1 From d9b08b9efece1f397143378938e626d0de29e911 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 18 May 2007 13:12:40 +0200 Subject: [PATCH] ocfs2: use generic_segment_checks Signed-off-by: Christoph Hellwig Signed-off-by: Mark Fasheh --- fs/ocfs2/file.c | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) (limited to 'fs') diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index d459eb9..ac6c964 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1419,36 +1419,6 @@ out: return total ? total : ret; } -static int ocfs2_check_iovec(const struct iovec *iov, size_t *counted, - unsigned long *nr_segs) -{ - size_t ocount; /* original count */ - unsigned long seg; - - ocount = 0; - for (seg = 0; seg < *nr_segs; seg++) { - const struct iovec *iv = &iov[seg]; - - /* - * If any segment has a negative length, or the cumulative - * length ever wraps negative then return -EINVAL. - */ - ocount += iv->iov_len; - if (unlikely((ssize_t)(ocount|iv->iov_len) < 0)) - return -EINVAL; - if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len)) - continue; - if (seg == 0) - return -EFAULT; - *nr_segs = seg; - ocount -= iv->iov_len; /* This segment is no good */ - break; - } - - *counted = ocount; - return 0; -} - static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, @@ -1471,7 +1441,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, if (iocb->ki_left == 0) return 0; - ret = ocfs2_check_iovec(iov, &ocount, &nr_segs); + ret = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); if (ret) return ret; -- cgit v1.1 From f4d43bd579f13219ffd3cae48432eab5bbac2d6f Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Sat, 26 May 2007 00:39:17 +0100 Subject: fix compat console unimap regression Why is it that since the 2f1a2ccb9c0de632ab07193becf5f7121794f6ae console UTF-8 fixes went into 2.6.22-rc1, the PowerMac G5 shows only inverse video question marks for the text on tty2-6? whereas tty1 is fine, and so is x86. No fault of that patch: by removing the old fallback behaviour, it reveals that 32-bit setfont running on 64-bit kernels has only really worked on the current console, the rest getting faked by that inadequate fallback. Bring the compat do_unimap_ioctl into line with the main one: PIO_UNIMAP and GIO_UNIMAP apply to the specified tty, not redirected to fg_console. Use the same checks, and most particularly, remember to check access_ok: con_set_unimap and con_get_unimap are using __get_user and __put_user. And the compat vt_check should ask for the same capability as the main one, CAP_SYS_TTY_CONFIG rather than CAP_SYS_ADMIN. Added in vt_ioctl's vc_cons_allocated check for safety, though failure may well be impossible. Signed-off-by: Hugh Dickins Signed-off-by: Linus Torvalds --- fs/compat_ioctl.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'fs') diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 65643de..6b44cdc 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -1194,6 +1194,7 @@ static int vt_check(struct file *file) { struct tty_struct *tty; struct inode *inode = file->f_path.dentry->d_inode; + struct vc_data *vc; if (file->f_op->ioctl != tty_ioctl) return -EINVAL; @@ -1204,12 +1205,16 @@ static int vt_check(struct file *file) if (tty->driver->ioctl != vt_ioctl) return -EINVAL; - + + vc = (struct vc_data *)tty->driver_data; + if (!vc_cons_allocated(vc->vc_num)) /* impossible? */ + return -ENOIOCTLCMD; + /* * To have permissions to do most of the vt ioctls, we either have - * to be the owner of the tty, or super-user. + * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. */ - if (current->signal->tty == tty || capable(CAP_SYS_ADMIN)) + if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) return 1; return 0; } @@ -1310,16 +1315,28 @@ static int do_unimap_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct unimapdesc32 tmp; struct unimapdesc32 __user *user_ud = compat_ptr(arg); int perm = vt_check(file); - - if (perm < 0) return perm; + struct vc_data *vc; + + if (perm < 0) + return perm; if (copy_from_user(&tmp, user_ud, sizeof tmp)) return -EFAULT; + if (tmp.entries) + if (!access_ok(VERIFY_WRITE, compat_ptr(tmp.entries), + tmp.entry_ct*sizeof(struct unipair))) + return -EFAULT; + vc = ((struct tty_struct *)file->private_data)->driver_data; switch (cmd) { case PIO_UNIMAP: - if (!perm) return -EPERM; - return con_set_unimap(vc_cons[fg_console].d, tmp.entry_ct, compat_ptr(tmp.entries)); + if (!perm) + return -EPERM; + return con_set_unimap(vc, tmp.entry_ct, + compat_ptr(tmp.entries)); case GIO_UNIMAP: - return con_get_unimap(vc_cons[fg_console].d, tmp.entry_ct, &(user_ud->entry_ct), compat_ptr(tmp.entries)); + if (!perm && fg_console != vc->vc_num) + return -EPERM; + return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), + compat_ptr(tmp.entries)); } return 0; } -- cgit v1.1 From df3c7244264f1d12562413aa32d56be802486516 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 24 May 2007 15:27:03 +1000 Subject: [XFS] Write at EOF may not update filesize correctly. The recent fix for preventing NULL files from being left around does not update the file size corectly in all cases. The missing case is a write extending the file that does not need to allocate a block. In that case we used a read mapping of the extent which forced the use of the read I/O completion handler instead of the write I/O completion handle. Hence the file size was not updated on I/O completion. SGI-PV: 965068 SGI-Modid: xfs-linux-melb:xfs-kern:28657a Signed-off-by: David Chinner Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_aops.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 4475588..7361861 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -701,7 +701,7 @@ xfs_is_delayed_page( else if (buffer_delay(bh)) acceptable = (type == IOMAP_DELAY); else if (buffer_dirty(bh) && buffer_mapped(bh)) - acceptable = (type == 0); + acceptable = (type == IOMAP_NEW); else break; } while ((bh = bh->b_this_page) != head); @@ -810,7 +810,7 @@ xfs_convert_page( page_dirty--; count++; } else { - type = 0; + type = IOMAP_NEW; if (buffer_mapped(bh) && all_bh && startio) { lock_buffer(bh); xfs_add_to_ioend(inode, bh, offset, @@ -968,8 +968,8 @@ xfs_page_state_convert( bh = head = page_buffers(page); offset = page_offset(page); - flags = -1; - type = IOMAP_READ; + flags = BMAPI_READ; + type = IOMAP_NEW; /* TODO: cleanup count and page_dirty */ @@ -999,14 +999,14 @@ xfs_page_state_convert( * * Third case, an unmapped buffer was found, and we are * in a path where we need to write the whole page out. - */ + */ if (buffer_unwritten(bh) || buffer_delay(bh) || ((buffer_uptodate(bh) || PageUptodate(page)) && !buffer_mapped(bh) && (unmapped || startio))) { - /* + /* * Make sure we don't use a read-only iomap */ - if (flags == BMAPI_READ) + if (flags == BMAPI_READ) iomap_valid = 0; if (buffer_unwritten(bh)) { @@ -1055,7 +1055,7 @@ xfs_page_state_convert( * That means it must already have extents allocated * underneath it. Map the extent by reading it. */ - if (!iomap_valid || type != IOMAP_READ) { + if (!iomap_valid || flags != BMAPI_READ) { flags = BMAPI_READ; size = xfs_probe_cluster(inode, page, bh, head, 1); @@ -1066,7 +1066,15 @@ xfs_page_state_convert( iomap_valid = xfs_iomap_valid(&iomap, offset); } - type = IOMAP_READ; + /* + * We set the type to IOMAP_NEW in case we are doing a + * small write at EOF that is extending the file but + * without needing an allocation. We need to update the + * file size on I/O completion in this case so it is + * the same case as having just allocated a new extent + * that we are writing into for the first time. + */ + type = IOMAP_NEW; if (!test_and_set_bit(BH_Lock, &bh->b_state)) { ASSERT(buffer_mapped(bh)); if (iomap_valid) -- cgit v1.1 From b4946ffb1860597b187d78d61ac6504177eb0ff8 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 30 May 2007 12:58:00 -0400 Subject: NFS: Fix a refcount leakage in O_DIRECT The current code is leaking a reference to dreq->kref when the calls to nfs_direct_read_schedule() and nfs_direct_write_schedule() return an error. This patch moves the call to kref_put() from nfs_direct_wait() back into nfs_direct_read() and nfs_direct_write() (which are the functions that actually took the reference in the first place) fixing the leak. Thanks to Denis V. Lunev for spotting the bug and proposing the original fix. Acked-by: Denis V. Lunev Acked-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/nfs/direct.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 0c542ec..00eee87 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -168,7 +168,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void) return dreq; } -static void nfs_direct_req_release(struct kref *kref) +static void nfs_direct_req_free(struct kref *kref) { struct nfs_direct_req *dreq = container_of(kref, struct nfs_direct_req, kref); @@ -177,6 +177,11 @@ static void nfs_direct_req_release(struct kref *kref) kmem_cache_free(nfs_direct_cachep, dreq); } +static void nfs_direct_req_release(struct nfs_direct_req *dreq) +{ + kref_put(&dreq->kref, nfs_direct_req_free); +} + /* * Collects and returns the final error value/byte-count. */ @@ -196,7 +201,6 @@ static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq) result = dreq->count; out: - kref_put(&dreq->kref, nfs_direct_req_release); return (ssize_t) result; } @@ -214,7 +218,7 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq) } complete_all(&dreq->completion); - kref_put(&dreq->kref, nfs_direct_req_release); + nfs_direct_req_release(dreq); } /* @@ -369,6 +373,7 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size if (!result) result = nfs_direct_wait(dreq); rpc_clnt_sigunmask(clnt, &oldset); + nfs_direct_req_release(dreq); return result; } @@ -716,6 +721,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz if (!result) result = nfs_direct_wait(dreq); rpc_clnt_sigunmask(clnt, &oldset); + nfs_direct_req_release(dreq); return result; } -- cgit v1.1 From 3f0a6766e0cc5a577805732e5adb50a585c58175 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Thu, 31 May 2007 11:31:55 +0800 Subject: a bug in ramfs_nommu_resize function, passing old size to vmtruncate It should be pass "newsize" to vmtruncate function to modify the inode->i_size, while the old size is passed to vmtruncate. This bug was caught by LTP truncate test case on Blackfin platform. After it was fixed, the LTP truncate test case passed. Signed-off-by: Bryan Wu Cc: David Howells Signed-off-by: Linus Torvalds --- fs/ramfs/file-nommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 3b481d5..9345a46 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -179,7 +179,7 @@ static int ramfs_nommu_resize(struct inode *inode, loff_t newsize, loff_t size) return ret; } - ret = vmtruncate(inode, size); + ret = vmtruncate(inode, newsize); return ret; } -- cgit v1.1