X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=0c988828d609660bc096c8cf01c944f6f8e633dc;hb=999393949c1ee8225d1703156c39575b1ed99cbb;hp=2d59b5da0450e22d5b9f8b21ae3562d3beab6d3c;hpb=3a43b6ca05ec2b8f0494f8619a82d25204b7b457;p=netatalk.git diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 2d59b5da..0c988828 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -328,8 +328,6 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si } else { eid = ADEID_RFORK; adflags |= ADFLAGS_RF; - if (!(access & OPENACC_WR)) - adflags |= ADFLAGS_NORF; } if (access & OPENACC_WR) { @@ -388,6 +386,16 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si if (ad_open(ofork->of_ad, upath, adflags, 0666) == 0) { ofork->of_flags |= AFPFORK_META; + if (ad_get_MD_flags(ofork->of_ad) & O_CREAT) { + LOG(log_debug, logtype_afpd, "afp_openfork(\"%s\"): setting CNID", upath); + cnid_t id; + if ((id = get_id(vol, ofork->of_ad, st, dir->d_did, upath, strlen(upath))) == CNID_INVALID) { + LOG(log_error, logtype_afpd, "afp_createfile(\"%s\"): CNID error", upath); + goto openfork_err; + } + (void)ad_setid(ofork->of_ad, st->st_dev, st->st_ino, id, dir->d_did, vol->v_stamp); + ad_flush(ofork->of_ad); + } } else { switch (errno) { case EACCES: @@ -575,7 +583,7 @@ int afp_setforkparams(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf _U_, s goto afp_setfork_err; } - err = ad_rtruncate(ofork->of_ad, size); + err = ad_rtruncate(ofork->of_ad, mtoupath(ofork->of_vol, of_name(ofork), ofork->of_did, utf8_encoding(obj)), size); if (st_size > size) ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, size, st_size -size, ofork->of_refnum); if (err < 0) @@ -791,6 +799,8 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si goto afp_read_err; } + AFP_READ_START((long)reqcount); + /* reqcount isn't always truthful. we need to deal with that. */ size = ad_size(ofork->of_ad, eid); @@ -798,7 +808,7 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si "afp_read(fork: %" PRIu16 " [%s], off: %" PRIu64 ", len: %" PRIu64 ", size: %" PRIu64 ")", ofork->of_refnum, (ofork->of_flags & AFPFORK_DATA) ? "data" : "reso", offset, reqcount, size); - if (offset > size) { + if (offset >= size) { err = AFPERR_EOF; goto afp_read_err; } @@ -837,11 +847,13 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si } #endif - *rbuflen = MIN(reqcount, *rbuflen); + *rbuflen = MIN(reqcount, dsi->server_quantum); - err = read_file(ofork, eid, offset, rbuf, rbuflen); - if (err < 0) + cc = read_file(ofork, eid, offset, ibuf, rbuflen); + if (cc < 0) { + err = cc; goto afp_read_done; + } LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd): got %jd bytes from file", @@ -854,18 +866,22 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si * we know that we're sending some data. if we fail, something * horrible happened. */ - if ((cc = dsi_readinit(dsi, rbuf, *rbuflen, reqcount, err)) < 0) + if ((cc = dsi_readinit(dsi, ibuf, *rbuflen, reqcount, err)) < 0) goto afp_read_exit; *rbuflen = cc; while (*rbuflen > 0) { - cc = read_file(ofork, eid, offset, rbuf, rbuflen); + /* + * This loop isn't really entered anymore, we've already + * sent the whole requested block in dsi_readinit(). + */ + cc = read_file(ofork, eid, offset, ibuf, rbuflen); if (cc < 0) goto afp_read_exit; offset += *rbuflen; /* dsi_read() also returns buffer size of next allocation */ - cc = dsi_read(dsi, rbuf, *rbuflen); /* send it off */ + cc = dsi_read(dsi, ibuf, *rbuflen); /* send it off */ if (cc < 0) goto afp_read_exit; *rbuflen = cc; @@ -883,6 +899,8 @@ afp_read_exit: afp_read_done: if (obj->options.flags & OPTION_AFP_READ_LOCK) ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount, ofork->of_refnum); + + AFP_READ_DONE(); return err; afp_read_err: @@ -1037,7 +1055,7 @@ int afp_closefork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, s ofork->of_refnum, (ofork->of_flags & AFPFORK_DATA) ? "data" : "rsrc"); if (of_closefork(obj, ofork) < 0 ) { - LOG(log_error, logtype_afpd, "afp_closefork(%s): of_closefork: %s", of_name(ofork), strerror(errno) ); + LOG(log_error, logtype_afpd, "afp_closefork: of_closefork: %s", strerror(errno) ); return( AFPERR_PARAM ); } @@ -1153,6 +1171,8 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s goto afp_write_err; } + AFP_WRITE_START((long)reqcount); + saveoff = offset; if (obj->options.flags & OPTION_AFP_READ_LOCK) { if (ad_tmplock(ofork->of_ad, eid, ADLOCK_WR, saveoff, reqcount, ofork->of_refnum) < 0) { @@ -1227,6 +1247,7 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s ofork->of_vol->v_appended += (newsize > oldsize) ? (newsize - oldsize) : 0; *rbuflen = set_off_t (offset, rbuf, is64); + AFP_WRITE_DONE(); return( AFP_OK ); afp_write_err: